Skip to main content

Building Your Contract

Run the following command to compile your smart contract:

cargo +nightly contract build

This special command will turn your ink! project into a Wasm binary which you can deploy to your chain. If all goes well, you should see a target folder which contains this .wasm file.

  target
└── flipper.wasm

Contract Metadata

By running the next command we'll generate the contract metadata (a.k.a. the contract ABI):

cargo +nightly contract generate-metadata

You should have a new JSON file (metadata.json) in the same target directory:

  target
├── flipper.wasm
└── metadata.json

Let's take a look at the structure inside:

  {
"metadataVersion": "0.1.0",
"source": {
"hash": "0x11ba777b3457bf64cb99421786c90d421afde1c56579aa3dae336e58ccc8f783",
"language": "ink! 3.0.0-rc1",
"compiler": "rustc 1.47.0-nightly"
},
"contract": {
"name": "flipper",
"version": "0.1.0",
"authors": [
"[your_name] "
]
},
"spec": {
"constructors": [
{
"args": [
{
"name": "init_value",
"type": {
"displayName": [
"bool"
],
"type": 1
}
}
],
"docs": [
" Constructor that initializes the `bool` value to the given `init_value`."
],
"name": [
"new"
],
"selector": "0xd183512b"
},
{
"args": [],
"docs": [
" Constructor that initializes the `bool` value to `false`.",
"",
" Constructors can delegate to other constructors."
],
"name": [
"default"
],
"selector": "0x6a3712e2"
}
],
"docs": [],
"events": [],
"messages": [
{
"args": [],
"docs": [
" A message that can be called on instantiated contracts.",
" This one flips the value of the stored `bool` from `true`",
" to `false` and vice versa."
],
"mutates": true,
"name": [
"flip"
],
"payable": false,
"returnType": null,
"selector": "0xc096a5f3"
},
{
"args": [],
"docs": [
" Simply returns the current value of our `bool`."
],
"mutates": false,
"name": [
"get"
],
"payable": false,
"returnType": {
"displayName": [
"bool"
],
"type": 1
},
"selector": "0x1e5ca456"
}
]
},
"storage": {
"struct": {
"fields": [
{
"layout": {
"cell": {
"key": "0x0000000000000000000000000000000000000000000000000000000000000000",
"ty": 1
}
},
"name": "value"
}
]
}
},
"types": [
{
"def": {
"primitive": "bool"
}
}
]
}

You can see that this file describes all the interfaces that can be used to interact with your contract.

  • Registry provides the strings and custom types used throughout the rest of the JSON.
  • Storage defines all the storage items managed by your contract and how to ultimately access them.
  • Contract stores information about the callable functions like constructors and messages a user can call to interact with your contract. It also has helpful information like the events that are emitted by the contract or any docs.

If you look close at the constructors and messages, you will also notice a selector which is a 4-byte hash of the function name and is used to route your contract calls to the correct functions.

Learn More

ink! provides a built-in overflow protection enabled on our Cargo.toml file. It is recommended to keep it enabled to prevent potential overflow errors in your contract.

[profile.release]
panic = "abort" <-- Panics shall be treated as aborts: reduces binary size
lto = true <-- enable link-time-optimization: more efficient codegen
opt-level = "z" <-- Optimize for small binary output
overflow-checks = true <-- Arithmetic overflow protection