ABI generator attributes
Unlike the old ABI generator tool, the new tool uses C++11 or GNU style attributes to mark actions
and tables
.
[[eosio::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
[[eosio::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__((eosio_action))
void testa( name n ){
// do something
}
struct [[eosio::action]] testa {
name n;
EOSLIB_SERIALIZE( testa, (n) )
};
struct __attribute__((eosio_action)) testa {
name n;
EOSLIB_SERIALIZE( testa, (n) )
};
If your action name is not a valid EOSIO name you can explicitly specify the name in the attribute c++ [[eosio::action("<valid action name>")]]
Example (two ways to declare a table for ABI generation):
struct [[eosio::table]] testtable {
uint64_t owner;
/* all other fields */
};
struct __attribute__((eosio_table)) testtable {
uint64_t owner;
/* all other fields */
};
typedef eosio::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++ [[eosio::table("<valid action name>")]]
.
For an example contract of ABI generation please see the file ./examples/abigen_test/test.cpp. You can generate the ABI for this file with eosio-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 generators 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 EOSIO.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 contracts 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
<h1 class="contract">ActionName</h1>
should be used, as this directs the ABI generator to attach this Ricardian contract to the specified action. - For each Ricardian clause the header
<h1 class="clause">ClauseID</h1>
should be used, as this directs the ABI generator to the clause id and the subsequent body. - The option
-R
has been added to eosio-cpp and eosio-abigen to add "resource" paths to search from, so you can place these files in any directory structure you like and use-R<path to file>
in the same vein as-I
for include paths. - To see these in use please see ./examples/hello/hello.contracts.md and ./examples/hello/hello.clauses.md.