1.2 To 1.3

Version 1.3

arisenlib C API

  • Removed the following typedefs to uint64_t:

  • account_name

  • permission_name

  • scope_name

  • table_name

  • action_name

  • Added a uint64_t typedef called capi_name to replace the removed typedefs above:

  • These have been replaced by capi_name and as a practice should not be used when writing C++ contract code. Instead, the new version of the arisen::name type from the arisenlib C++ API should be used to replace these instances. This decision was made because of bad implicit casting issues with uint64_t and the new pattern should allow for better type safety.

  • Removed symbol_name typedef:

  • This has no C equivalent to replace it. When writing C++ contract code, the arisen::symbol_code struct should be used instead. As with the previously mentioned named types, this was removed and replaced with arisen::symbol_code to allow for better type safety in contracts. To use a symbol, i.e. symbol name and precision, use the arisen::symbol class.

  • Removed time and weight_type typedefs.

  • Removed the transaction_id_type and block_id_type typedefs.

  • Removed the account_permission struct.

  • Renamed the following typedefs:

  • checksum160 -> capi_checksum160

  • checksum256 -> capi_checksum256

  • checksum512 -> capi_checksum512

  • public_key -> capi_public_key

  • signature -> capi_signature

  • Removed the non-existent intrinsics declarations require_write_lock and require_read_lock.

arisenlib C++ API

  • Removed arisenlib/vector.hpp:

  • Removed alias arisen::vector and typedef bytes.

  • Going forward contract writers should include from the STL and use std::vector instead of bytes.

  • Removed arisenlib/types.hpp.

  • Removed arisenlib/optional.hpp. Use std::optional as a replacement.

  • Removed arisenlib/core_symbol.hpp. The contract writer should explicitly specify the symbol.

  • Added arisenlib/name.hpp.

arisenlib/types.hpp

  • Moved the typedef arisen::extensions_types to arisenlib/transaction.hpp.
  • Removed comparison functions for checksum structs.
  • Removal of arisen::char_to_symbol, arisen::string_to_name, arisen::name_suffix functions
  • Removal of the N macro. The ""_n operator or the name constructor should be used as a type safe
    replacement. Example: N(foo) -> "foo"_n, or N(foo) -> name("foo").
  • Moved arisen:name struct definition and ""_n operator to arisenlib/name.hpp.

arisenlib/name.hpp

  • Removed implicit and explicit conversions to uint64_t.
  • Added enum class arisen::name::raw which is implicitly converted from an arisen::name (used for template non-type parameters).
  • Added bool conversion operator for conditionally testing if a name is empty.
  • All constructors are now constexpr. These take either a uint64_t, an arisen::name::raw or a std::string_view.
  • Added constexpr methods arisen::name::length and arisen::name::suffix.
  • Added equivalence, inverted equivalence and less than operators to arisen::name.

arisenlib/symbol.hpp

  • Removed arisen::symbol_type struct and replaced with arisen::symbol class.
  • Added struct arisen::symbol_code:
  • Added two constexpr constructors that take either a raw uint64_t or an std::string_view.
  • Added constexpr methods is_valid, length and raw.
  • Added a print method.
  • Added bool conversion operator to test is symbol_code is empty.
  • Removed arisen::string_to_symbol, arisen::is_valid_symbol, arisen::symbol_name_length functions.
  • Removed the S macro. The symbol constructor should be used as a type safe replacement. Example: S(4,RIX) -> symbol(symbol_code("RIX"), 4) (or simply symbol("RIX", 4) as of v1.3.1).
  • Added struct arisen::symbol:
  • Added three constexpr constructors that take either a raw uint64_t, symbol_code and a uint8_t precision or an std::string_view and a uint8_t precision.
  • Added constexpr methods is_valid, precision, code, and raw. These, respectively, check if the symbol is valid, get the uint8_t precision, get the symbol_code part of the symbol, and get the raw uint64_t representation of symbol.
  • Added equivalence, inverted equivalence and less than operators to arisen::symbol.
  • Modified struct arisen::extended_symbol:
  • Restricted fields to private.
  • Added constexpr constructor that takes a arisen::symbol and an arisen::name.
  • Added constexpr methods get_symbol and get_contract.
  • Made existing comparison operators constexpr.

arisenlib/asset.hpp

  • The main constructor now requires a int64_t (quantity) and arisen::symbol explicitly.
  • The default constructor no longer initializes the instance to a valid zero quantity asset with a symbol equivalent to "core symbol". Instead the default constructed arisen::asset is a bit representation of all zeros (which will cause is_valid to fail) so that check is bypassed to allow for multi_index and datastream to work.
  • Old contracts that use arisen::asset() should be changed to either use the core symbol of the specific chain they are targeting i.e. arisen::asset(0, symbol(symbol_code("RIX"),4)). To reduce writing symbol(symbol_code("RIX"),4) over and over, a constexpr function to return the symbol or constexpr global variable should be used.

arisenlib/contract.hpp

  • The constructor for arisen::contract now takes an arisen::name for the receiver, an arisen::name for the code, and a arisen::datastream<const char*> for the datastream used for the contract. The last argument is for manually unpacking an action, see the section on arisen::ignore for a more indepth usage.

arisenlib/dispatcher.hpp

  • Renamed the macro ARISEN_ABI to ARISEN_DISPATCH as this is more descriptive of what this macro actually does.
  • Modified the definition of ARISEN_DISPATCH to work with the new constructor for arisen::contract.

arisenlib/multi_index.hpp

  • The first template parameter for indexed_by now requires the argument be convertible to arisen::name::raw (replacing uint64_t).
  • The first template parameter for multi_index now requires the argument be convertible to arisen::name::raw (replacing uint64_t).
  • The constructor now takes an arisen::name type for the code (replacing uint64_t). Scope is still uint64_t.
  • Various other replacements of uint64_t to arisen::name.

arisenlib/action.hpp

  • Added C++ function arisen::require_auth.
  • Added C++ function arisen::has_auth.
  • Added C++ function arisen::is_account.
  • Redefined arisen::permission_level to use arisen::name in place of uint64_t.
  • Removed the macro ACTION. (The identifier ACTION has been reused for another macro described below in the Macros section.)

arisenlib/permission.hpp

  • The optional provided_keys argument of the function arisen::check_transaction_authorization is now of the type std::set<arisen::public_key> rather than the type std::set<capi_public_key>. C++ contract code should most likely be using the arisen::public_key struct (defined in "arisenlib/public_key.hpp") if they need to deal with ARISEN-compatible public keys rather than the capi_public_key struct (now renamed from its original name of ::public_key) from the arisenlib C API. Note that existing contract code that just referred to the type public_key without namespace qualification may have accidentally been using the capi_public_key struct and therefore should ideally be modified to use the arisen::public_key C++ type.
  • The account and permission arguments of arisen::check_permission_authorization are both arisen::name now instead of uint64_t.

arisenlib/ignore.hpp

  • Added new type ignore:

  • This type acts as a placeholder for actions that don't want to deserialize their fields but want the t ypes to be reflected in the ABI.

  • Added new type ignore_wrapper:

  • This allows for calling SEND_INLINE_ACTION with ignore_wrapper(some_value) against an action with an ignore of matching types.

ACTION action(ignore<some_type>) { some_type st; _ds >> st; }

Macros

  • Added ACTION macro which is simply a shortcut for [[arisen::action]] void.
  • Added TABLE macro which is simply a shortcut for struct [[arisen::table]].
  • Added CONTRACT macro which is simply a shortcut for class [[arisen::contract]].

CMake

  • Added arisen.cdt-config.cmake to allow for find_package(arisen.cdt). See arisen.cdt/examples/hello or arisen.cdt/examples/template for an example.
  • Added new macro add_contract. This new contract takes a contract name, cmake target, then any normal arguments you would give to add_executable. See arisen.cdt/examples/hello or arisen.cdt/examples/template.
  • New version checking mechanism is included. See arisen.contracts/CMakeLists.txt to see this in use.

libc

  • Replaced printf, sprintf, and snprintf with new minimal variants. This allows contracts to use these functions without causing stack overflow issues.

libcxx

  • Removed sstream with the intent to return this after more has been done.
  • Added __cxa_pure_virtual to allow for pure virtual methods in contract classes.
  • std::to_string now works without the issues of stack overflows.

attributes

  • Added [[arisen::ignore]] attribute to flag a type as being ignored by the deserializer. This attribute is primarily only used for internal use within arisenlib.
  • Added [[arisen::contract]] attribute. This new attribute is used to mark a contract class as "contract" with the name being either the C++ name of the class or a user specified name (i.e. [[arisen::contract("somecontract")]]). This attribute can also be used in conjunction with the arisen::action and arisen::table attributes for tables that you would like to define outside of the arisen::contract class. This is used in conjunction with either the raw arisen-cpp option --contract , -o .wasm or with CMake add_contract. It acts as a filter enabling contract developers to include a header file with attributes from another contract (e.g. arisen.token) while generating an ABI devoid of those actions and tables.
#include <arisenlib/arisen.hpp>
using namespace arisen;
CONTRACT test : public arisen::contract {
public:
   using contract::contract;
   ACTION acta(){}
   TABLE taba {
      uint64_t a;
      float b;
      uint64_t primary_key() const { return a; }
   };
};
struct [[arisen::table, arisen::contract("test")]]
tabb {
   uint64_t a;
   int b;
};
typedef arisen::multi_index<"testtaba"_n, test::taba> table_a;
typedef arisen::multi_index<"testtabb"_n, tabb> table_b;
ARISEN_DISPATCH( test, (acta) )

The above code will produce the tables testtaba and testtabb in your ABI. Example: arisen-cpp -abigen test.cpp -o test.wasm will mark this compilation and ABI generation for the arisen::contract test. The same thing can be done with arisen-cpp -abigen test.cpp -o test_contract.wasm --contract test or with the CMake command add_contract( test, test_contract, test.cpp ). Either of the previous two approaches will produce a test_contract.wasm and test_contract.abi generated under the context of the contract name of test.

Boost

Boost is now part of the library. No more external dependence on Boost and all system inclusion are within it's sysroot. (Boost will be removed in a future release.)

ABI generator attributes

Unlike the old ABI generator tool, the new tool uses C++11 or GNU style attributes to mark actions and tables.

[[arisen::action]]

This attribute marks either a struct or a method as an action. Example (four ways to declare an action for ABI generation):

// this is the C++11 and greater style attribute
[[arisen::action]]
void testa( name n ) {
   // do something
}

// this is the GNU style attribute, this can be used in C code and prior to C++ 11
__attribute__((arisen_action))
void testa( name n ){
   // do something
}

struct [[arisen::action]] testa {
   name n;
   EOSLIB_SERIALIZE( testa, (n) )
};

struct __attribute__((arisen_action)) testa {
   name n;
   EOSLIB_SERIALIZE( testa, (n) )
};

If your action name is not a valid ARISEN name you can explicitly specify the name in the attribute c++ [[arisen::action("")]]

Example (two ways to declare a table for ABI generation):

struct [[arisen::table]] testtable {
   uint64_t owner;
   /* all other fields */
};

struct __attribute__((arisen_table)) testtable {
   uint64_t owner;
   /* all other fields */
};

typedef arisen::multi_index<"tablename"_n, testtable> testtable_t;

If you don't want to use the multi-index you can explicitly specify the name in the attribute c++ [[arisen::table("")]].

For an example contract of ABI generation see the file ./examples/abigen_test/test.cpp. You can generate the ABI for this file with arisen-abigen test.cpp --output=test.abi.

Fixing an ABI or Writing an ABI Manually

The sections to the ABI are pretty simple to understand and the syntax is purely JSON, so it is reasonable to write an ABI file manually.
The ABI generation will never be completely perfect for every contract written. Advanced features of the newest version of the ABI will require manual construction of the ABI, and odd and advanced C++ patterns could capsize the generator's type deductions. So having a good knowledge of how to write an ABI should be an essential piece of knowledge of a smart contract writer.
Please refer to developers.eos.io "How to Write an ABI File" to learn about the different sections of an ABI.

Adding Ricardian Contracts and Clauses to ABI

As of ARISEN.CDT v1.4.0, the ABI generator will try to automatically import contracts and clauses into the generated ABI. There are a few caveats to this, one is a strict naming policy of the files and an HTML tag used to mark each Ricardian contract and each clause.

  • The Ricardian contract should be housed in a file with the name .contracts.md and the clauses should be in a file named .clauses.md.

  • For each Ricardian contract, the header

    ActionName

    should be used, as this directs the ABI generator to attach this Ricardian contract to the specified action.

  • For each Ricardian clause, the header

    ClauseID

    should be used, as this directs the ABI generator to the clause id and the subsequent body.

  • The option -R has been added to arisen-cpp and arisen-abigen to add "resource" paths to search from, so you can place these files in any directory structure you like and use -R in the same vein as -I for include paths.

  • For exemplification see hello.contracts.md.