AIOU Chain Docs

AIOU Chain Docs

  • Docs
  • Languages iconEnglish
    • 中文

›Smart Contract

Getting started

  • Overview
  • Quickstart

AIOU Design and Concepts

  • Account
  • Economic model

Smart Contract

  • Smart Contract Quick Start
  • AIOU Blockchain API
  • Update Contract
  • Generate Receipt in Smart Contract
  • Create IRC20 Token

Running AIOU node

  • Join AIOU Network
  • Become Servi Node

Reference

  • API
  • System Contract
  • Economic Contract
  • Token Contract
  • Gas Charge Table

AIOU Javascript SDK

  • AIOU
  • Blockchain
  • KeyPair
  • Transaction

AIOU Tech Internals

  • VM
  • Database
  • Network layer

AIOU Blockchain API

AIOU Blockchain API

There objects below can be used directly inside contract codes.

storage object

All variables will be stored in memory in runtime. AIOU provides storage object to help developers persist data in smart contracts. APIs without 'global' prefix are used to get/set storage of the calling contract. APIs with 'global' prefix are used to get storage of other contracts.

Storage API

put(key, value, payer=contractOwner)

Simply put a key-value pair into storage.

Parameter ListParameter TypeRemark
keystringcannot be longer than 65536 bytes
valuestringcannot be longer than 65536 bytes
payerstring(optional)it determines who will pay for the ram usage. This parameter is optional. If it is empty, the contract publisher will pay for the ram usage.

Returns: none

example:

// insert a k-v pair into storage and cost ram from contract owner
storage.put("test-key", "test-value");

// insert a k-v pair into storage and cost ram from transaction publisher
storage.put("test-key", "test-value", tx.publisher);

get(key)

Simply retrieve the value from storage using key.

Parameter ListParameter TypeRemark
keystring

Returns: value in string type if exists; null if not exists.

example:

let v = storage.get("test-key");
if (v !== null) {
    ...
}

has(key)

Check if the key exists in the storage.

Parameter ListParameter TypeRemark
keystring

Returns: bool (true if exists, false if not exists)

example:

if (storage.has("test-key")) {
    ...
}

del(key)

Simply delete a key-value pair from storage using key.

Parameter ListParameter TypeRemark
keystring

Returns: none

example:

storage.del("test-key")

mapPut(key, field, value, payer=contractOwner)

Map put a (key, field, value) pair. use key+field to find value.

Parameter ListParameter TypeRemark
keystringcannot be longer than 65536 bytes
fieldstringcannot be longer than 65536 bytes
valuestringcannot be longer than 65536 bytes
payerstring(optional)it determines who will pay for the ram usage. This parameter is optional. If it is empty, the contract publisher will pay for the ram usage.

Returns: none

example:

// insert a key-field-value pair into storage and cost ram from contract owner
storage.mapPut("test-key", "test-field", "test-value");

// insert a key-field-value pair into storage and cost ram from transaction publisher
storage.mapPut("test-key", "test-field", "test-value", tx.publisher);

mapGet(key, field)

Map Get a (key, field) pair, use key + field to find value

Parameter ListParameter TypeRemark
keystring
fieldstring

Returns: value in string type if exists; null if not exists.

example:

let v = storage.mapGet("test-key", "test-field");
if (v !== null) {
    ...
}

mapHas(key, field)

Map check a (key, field) pair existence, use key+field to check.

Parameter ListParameter TypeRemark
keystring
fieldstring

Returns: bool (true if exists, false if not exists)

example:

if (storage.mapHas("test-key", "test-field")) {
    ...
}

mapKeys(key)

Map Get fields inside a key.

Attention:

1. This API only stores 256 fields at most, and the field exceeded will not be stored and will not be returned in this API.
2. If you need to get all keys of a map, it is recommended that you maintain them yourself and not use this API.

Parameter ListParameter TypeRemark
keystring

Returns: array[string] (array of fields)

mapLen(key)

Return len(mapKeys()).

The attention is the same as mapKeys.

Parameter ListParameter TypeRemark
keystring

Returns: int (number of fields)

mapDel(key, field)

Map Delete a (key, field, value) pair, use key+field to delete value.

Parameter ListParameter TypeRemark
keystring
fieldstring

Returns: none

Global Storage API

APIs used to get storage of other contracts.

globalHas(contract, key)

Check if the key exists in the given contract's storage.

Parameter ListParameter TypeRemark
contractstringthe contract id
keystring

Returns: bool (true if exists, false if not exists)

example:

if (storage.globalHas("Contractxxxxxx", "test-key")) {
    ...
}

globalGet(contract, key)

Get value from the given contract's storage using key.

Parameter ListParameter TypeRemark
contractstringthe contract id
keystring

Returns: string of value if exists, null if not exists

example:

let v = storage.globalGet("Contractxxxxxx", "test-key");
if (v !== null) {
    ...
}

globalMapHas(contract, key, field)

Map check if a (key, field) pair exists in the given contract's storage, use key+field to check.

Parameter ListParameter TypeRemark
contractstringthe contract id
keystring
fieldstring

Returns: bool (true if exists, false if not exists)

example:

// read auth.aiou contract's storage to judge whether an account exists
accountExists(account) {
    return storage.globalMapHas("auth.aiou", "auth", account);
}

globalMapGet(contract, key, field)

Map get a (key, field) pair from global storage, use key+field to check.

Parameter ListParameter TypeRemark
contractstringthe contract id
keystring
fieldstring

Returns: string of value if exists, null if not exists

example:

let v = storage.globalMapGet("Contractxxxxxx", "test-key", "test-field");
if (v !== null) {
       ...
}

globalMapLen(contract, key)

Map count number of fields inside a key from global storage.

The attention is the same as mapKeys.

Parameter ListParameter TypeRemark
contractstringthe contract id
keystring

Returns: int (number of fields)

globalMapKeys(contract, key)

Map Get fields inside a key from global storage.

The attention is the same as mapKeys.

Parameter ListParameter TypeRemark
contractstringthe contract id
keystring

Returns: array[string] (array of fields)

blockchain object

blockchain object is used to call system API, and call other contract's abi.

transfer(from, to, amount, memo)

Transfer aiou token.

Parameter ListParameter TypeRemark
fromstringaccount who sends token
tostringaccount who receives token
amountstringthe amount of token transferred
memostringadditional information

Returns: none

example:

// transfer transaction publisher's 1.23 aiou to testacc
blockchain.transfer(tx.publisher, "testacc", "1.23", "this is memo")

withdraw(to, amount, memo)

Withdraw aiou token from contract. It equals to:

blockchain.transfer(blockchain.contractName(), to, amount, memo)

Parameter ListParameter TypeRemark
tostringaccount who receives token
amountstringthe amount of token transferred
memostringadditional information

Returns: none

example:

// transfer 1.23 aiou to testacc from this contract
blockchain.withdraw(tx.publisher, "1.23", "this is memo")

deposit(from, amount, memo)

Deposit aiou token to contract. It equals to:

blockchain.transfer(from, blockchain.contractName(), amount, memo)

Parameter ListParameter TypeRemark
fromstringaccount who receives token
amountstringthe amount of token transferred
memostringadditional information

Returns: none

example:

// transfer 1.23 aiou to contract from transaction publisher
blockchain.deposit(tx.publisher, "1.23", "this is memo")

contractName()

Get contract id.

Parameters: none

Returns: string of contract id

publisher()

Get transaction publisher.

Parameters: none

Returns: string of tx publisher

contractOwner()

Get contract owner.

Parameters: none

Returns: string of contract publisher

call(contract, abi, args)

Call contract's abi using args.

Parameter ListParameter TypeRemark
contractstringcontract id
abistring
argsarray/stringthe array of arguments, or the json string of it

Returns: Array containing a string which is the json string of what the called contract returns.

example:

// query admin's aiou balance by calling balanceOf of token.aiou 
let ret = blockchain.call("token.aiou", "balanceOf", ["aiou", "admin"])
console.log(ret[0]) // attention: ret[0] is what balanceOf returns

// get a vote result by calling getResult of vote.aiou
let ret = blockchain.call("vote.aiou", "getResult", ["1"])
let voteRes = JSON.parse(ret[0]) // what getResult of vote.aiou returns is an array, so we have to json parse it.

callWithAuth(contract, abi, args)

Call contract's abi using args with the contract's authority.

Parameter ListParameter TypeRemark
contractstringcontract id
abistring
argsarray/stringthe array of arguments, or the json string of it

Returns: Array containing a string which is the json string of what the called contract returns.

example:

// transfer 20 aiou to testacc
blockchain.callWithAuth("token.aiou", "transfer", ["aiou", blockchain.contractName(), "testacc", "20", ""]);

// if we use call, it will throw an error since transferring contract's token needs its authority 
blockchain.call("token.aiou", "transfer", ["aiou", blockchain.contractName(), "testacc", "20", ""]); // throw error

requireAuth(account, permission)

Check whether a given account's given permission is provided.

Parameter ListParameter TypeRemark
accountstring
permissionstring

Returns: bool (true if the permission is provided, false if not)

example:

// check whether testacc's active permission is provided
// that means whether the transaction contains the signature of testacc's active key
const ret = blockchain.requireAuth('testacc', 'active');
if (ret !== true) {
    throw new Error("require auth failed");
}

receipt(data)

Generate receipt.

Parameter ListParameter TypeRemark
datastring

Returns: none

example:

testReceipt() {
    blockchain.receipt("some receipt content")
}

After calling testReceipt of this contract, there will be a such record in TxReceipt:

"receipts": [
    {
        "funcName": "Contractxxxxx/testReceipt",
        "content": "some receipt content"
    }
]

event(data)

Post event.

Parameter ListParameter TypeRemark
datastring

Returns: none

example:

testEvent() {
    blockchain.event("some event content")
}

After calling testEvent of this contract, there will be event which you could get by calling subscribe:

curl -X POST http://127.0.0.1:30001/subscribe -d '{"topics":["CONTRACT_EVENT"], "filter":{"contract_id":"Contractxxxxx"}}'

{"result":{"event":{"topic":"CONTRACT_EVENT","data":"some event content","time":"1557150634515314000"}}}

tx object and block object

tx object contains current transaction information. Here's its attributes:

{
    time: 1541541540000000000, // nano second
    hash: "4mBbjkCYJQZz7hGSdnRKCLgGEkuhen1FCb6YDD7oLmtP",
    expiration: 1541541540010000000, // nano second
    gas_limit: 100000,
    gas_ratio: 100,
    auth_list: {"AIOU4wQ6HPkSrtDRYi2TGkyMJZAB3em26fx79qR3UJC7fcxpL87wTn":2},
    publisher: "user0"
}

example:

console.log(tx.publisher)

block object contrains current block information. Here's its attributes:

{
    number: 132,
    parent_hash: "4mBbjkCYJQZz7hGSdnRKCLgGEkuhen1FCb6YDD7oLmtP",
    witness: "AIOU4wQ6HPkSrtDRYi2TGkyMJZAB3em26fx79qR3UJC7fcxpL87wTn",
    time: 1541541540000000000 // nano second
}

example:

console.log(block.parent_hash)

AIOUCrypto object

AIOUCrypto provides hash function and signature verification function.

sha3(data)

Calculate sha3-256 hash.

Parameter ListParameter TypeRemark
datastring

Returns: string which is the result of base58 encode of hash byte array. (base58\_encode(sha3\_256(data)))

example:

AIOUCrypto.sha3("Fule will be expensive. Everyone will have a small car.") // result: EBNarfcGkAczpeiSJwtUfH9FEVd1xFhdZis83erU9WNu

Returns: base58_encode(sha3_256(data))

verify(algo, message, signature, pubkey)

Signature verification. Both ed25519 and secp256k1 algorithms are supported.

Parameter ListParameter TypeRemark
algostringcan only be "ed25519" or "secp256k1"
messagestringbase58 encoded original text to be signed
signaturestringbase58 encoded signature to be checked
pubkeystringbase58 encoded public key of the corresponding private key used for signing
  • Returns: int, 1 (succees) or 0 (failure)

example:

// choose ed25519 algorithm
// the base58 encoded private key is "4PTQW2hvwZoyuMdgKbo3iQ9mM7DTzxSV54RpeJyycD9b1R1oGgYT9hKoPpAGiLrhYA8sLQ3sAVFoNuMXRsUH7zw6"
// the base58 encoded public key is "2vSjKSXhepo7vmbPQHFcnEvx8mWRFrf46DaTX1Bp3TBi"
// the origial text is "hello world"
// "StV1DL6CwTryKyV" is base58 encoded result of "hello world"
// "38V8bZC4e78pU7zBN86CF8R8ip76Rhf3vyiwTQR2MVkqHesmUbZJVmN8AE6eWhQg6ekKaa2H4iB4JJibC5stBRrN" is base58 encoded signature signed by the private key above
// So the result of verification should be 1:
let v = AIOUCrypto.verify("ed25519", "StV1DL6CwTryKyV", "38V8bZC4e78pU7zBN86CF8R8ip76Rhf3vyiwTQR2MVkqHesmUbZJVmN8AE6eWhQg6ekKaa2H4iB4JJibC5stBRrN", "2vSjKSXhepo7vmbPQHFcnEvx8mWRFrf46DaTX1Bp3TBi"); // v = 1

Float64, Int64 and BigNumber object

In contract, we could use Float64, Int64 and BigNumber to do high precision calculation.
Float64 APIs can be found here.
Int64 APIs can be found here.
BigNumber APIs can be found here.

example:

let bonus = new Float64("1.0123456789");
let earning = bonus.div(2).toFixed(8); // earning is "0.50617283"
blockchain.withdraw("testacc", earning, "");

Disabled Javascript Methods

Some functions of Javascript is forbidden for security reasons.
This document gives a list of allowed and forbidden APIs.

← Smart Contract Quick StartUpdate Contract →
  • storage object
    • Storage API
    • Global Storage API
  • blockchain object
  • tx object and block object
  • AIOUCrypto object
  • Float64, Int64 and BigNumber object
  • Disabled Javascript Methods
AIOU Chain Docs
Community
BlogGitHubStar
Facebook Open Source
Copyright © 2021 Your Name or Your Company Name