AIOU Chain Docs

AIOU Chain Docs

  • Docs
  • Languages iconEnglish
    • 中文

›Reference

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

API

/getNodeInfo

GET

Returns information of the AIOU server node

Request

A request may look like this:

curl http://127.0.0.1:30001/getNodeInfo

Response

A successful response may look like this:

200 OK

{
    "build_time": "20190329_164908+0800",
    "git_hash": "5d0d3917bae2afab2758c7fe0519b95981252901",
    "mode": "ModeNormal",
    "network": 
    {
        "id": "12D3KooWQ1Uh2tu9GLybc6PwwZHfKkCSFQ3hS9wFUD7mF3xW5KwC",
        "peer_count": 30
    },
    "code_version": "3.0.7",
    "server_time": "1554292230570963220"
}

KeyTypeDescription
build_timestringBuilding time of the 'server' binary
git_hashstringGit hash of the 'iserver' binary
modestringCurrent mode of the server. It can be one of 'ModeInit', 'ModeNormal' and 'ModeSync'
networkNetworkInfoNetwork information of the node
code_versionstringthe version of code
server_timestringthe current timestamp of the server, unit is nano second

NetworkInfo

KeyTypeDescription
idstringNode ID in the p2p network
peer_countint32Peer count of the node

/getChainInfo

GET

Returns information of the AIOU blockchain

Request

A request may look like this:

curl http://127.0.0.1:30001/getChainInfo

Response

A successful response looks like this:

200 OK

{
    "net_name": "debugnet",
    "protocol_version": "1.0",
    "chain_id": 1024,
    "head_block": "16041",
    "head_block_hash": "DLJVtko6nQnAdvQ7y6dXHo3WMdG324yRLz8tPKk9tGHu",
    "lib_block": "16028",
    "lib_block_hash": "8apn7vCvQ6s9PFBzGfaXrvyL5eAaLNc4mEAgnTMoW8tC",
    "witness_list": ["AIOU2K9GKzVazBRLPTkZSCMcyMayKv7dWgdHD8uuWPzjfPdzj93x6J", "AIOU2YKPmRDGy5xLR7Gv65CN5nQ3vMmVhRjAsEM7Gj9xcB1LWgZUAd", "AIOU7E4T5rG9wjPZXDeM1zjhhWU3ZswtPQ1heeRUFUxntr65sYRBi"],
    "lib_witness_list": ["AIOU2K9GKzVazBRLPTkZSCMcyMayKv7dWgdHD8uuWPzjfPdzj93x6J", "AIOU2YKPmRDGy5xLR7Gv65CN5nQ3vMmVhRjAsEM7Gj9xcB1LWgZUAd", "AIOU7E4T5rG9wjPZXDeM1zjhhWU3ZswtPQ1heeRUFUxntr65sYRBi"],
    "pending_witness_list": ["AIOU2K9GKzVazBRLPTkZSCMcyMayKv7dWgdHD8uuWPzjfPdzj93x6J", "AIOU2YKPmRDGy5xLR7Gv65CN5nQ3vMmVhRjAsEM7Gj9xcB1LWgZUAd", "AIOU7E4T5rG9wjPZXDeM1zjhhWU3ZswtPQ1heeRUFUxntr65sYRBi"],
    "head_block_time": "1552917911507043000",
    "lib_block_time": "1552917911507043000"
}
KeyTypeDescription
net_namestringNetwork name, such as "mainnet" or "testnet"
protocol_versionstringaiou protocol version
chain_iduint32aiou chain id
head_blockint64the lastest block height
head_block_hashstringthe hash of the lastest block
lib_blockint64height of irreversible blocks
lib_block_hashint64hash of irreversible blocks
witness_listrepeated stringlist of pubkeys for the current block production nodes
lib_witness_listrepeated stringlist of pubkeys for the block production nodes of the last irreversible block time
pending_witness_listrepeated stringlist of pubkeys for the next round block production nodes
head_block_timeint64time of head block
lib_block_timeint64time of last irreversible block

/getGasRatio

GET

Get the GAS multiplier information, so that users may set their desired GAS trading multipliers. We recommend a slightly higher gas ratio than lowest_gas_ratio so that transactions will be published timely.

Request

A request may look like this:

curl http://127.0.0.1:30001/getGasRatio

Response

A successful response may look like this:

200 OK

{
    "lowest_gas_ratio": 1.5,
    "median_gas_ratio": 1.76
}
KeyTypeDescription
lowest_gas_ratiodoublethe lowest gas ratio of the most recently packed blocks
median_gas_ratiodoublethe median gas ratio of the most recently packed blocks

/getRAMInfo

GET

Get RAM information for the current blockchain, including usage and price.

Request

A request may look like this:

curl http://127.0.0.1:30001/getRAMInfo

Response

A successful response may look like this:

200 OK

{
    "available_ram": "96207067431",
    "buy_price": 0.04227129323234719,
    "sell_price": 0.00014551844642842057,
    "total_ram": "137438953472",
    "used_ram": "41231886041"
}
KeyTypeDescription
available_ramint64RAM available, in byte
used_ramint64The amount of RAM sold, in byte
total_ramint64The system's total RAM count, in byte
buy_pricedoubleThe buying price of RAM, in AIOU/byte
sell_pricedoubleThe selling price of RAM, in AIOU/byte

/getTxByHash

GET

Fetches the transaction by its base58 encoded hash

Request

A request may look like this:

curl http://127.0.0.1:30001/getTxByHash/6eGkZoXPQtYXdh7dBSXe2L1ckUCDj4egRn4fXtS2ACnR
KeyTypeDescription
hashstringhash of the transaction

Response

A successful response may look like this:

200 OK

{
    "status": "IRREVERSIBLE",
    "transaction": {
        "hash": "6eGkZoXPQtYXdh7dBSXe2L1ckUCDj4egRn4fXtS2ACnR",
        "time": "1544269519362042000",
        "expiration": "1544279519362041000",
        "gas_ratio": 1,
        "gas_limit": 50000,
        "delay": "0",
        "chain_id": 1024,
        "actions": [{
            "contract": "ContractTBv8ZDKUhTyeS4MomdcHRrXnJMELa5usSMHP6QJntFQ",
            "action_name": "transfer",
            "data": "[\"admin\",\"i1544269477\",1]"
        }],
        "signers": [],
        "publisher": "admin",
        "referred_tx": "",
        "amount_limit": [],
        "tx_receipt": null
    },
    "block_number": "4047298"
}
KeyTypeDescription
statusenumPENDING- transaction is cached, PACKED - transaction is in reversible blocks, IRREVERSIBLE - transaction is in irreversible blocks
transactionTransactionTransaction data
block_numberstringthe number of the block which the tx is in

Transaction

KeyTypeDescription
hashstringtransaction's hash
timeint64timestamp of the transaction
expirationint64the expiration of the transaction
gas_ratiodoubleGAS ratio, we recommend it to be 1.00 (1.00 – 100.00). Raise the ratio to let the network pack it faster
gas_limitdoubleUpper limits of GAS. This transaction will never cost more GAS than this amount
delayint64Transactions will be delayed by this much, in nanosecond
chain_iduint32id of blockchain on which the transaction could be executed
actionsrepeated Actionthe smallest transaction execution unit
signersrepeated stringlist of transaction signatures
publisherstringsender of the transaction, who is responsible for fees
referred_txstringdependency of transaction generation; used for delayed transactions
amount_limitrepeated AmountLimitUsers may specify token limits. For example, {"aiou": 100} specifies each signers will not spend more than 100 AIOU for the transaction
tx_receiptTxReceiptthe receipt of the transaction Action

Action

KeyTypeDescription
contractstringcontract name
action_namestringfunction name of the contract
datastringSpecific parameters of the call. Put every parameter in an array, and JSON-serialize this array. It may looks like ["a_string", 13]

AmountLimit

KeyTypeDescription
tokenstringtoken name
valuedoublecorresponding token limit

TxReceipt

KeyTypeDescription
tx_hashstringhash of the transaction
gas_usagedoubleGAS consumption of the transaction
ram_usagemap<string, int64>RAM consumption for the transaction. map-key is account name, and value is RAM amount
status_codeenumStatus of the transaction. SUCCESS; GAS_RUN_OUT - insufficient GAS; BALANCE_NOT_ENOUGH - insufficient balance; WRONG_PARAMETER; RUNTIME_ERROR - a run-time error; TIMEOUT; WRONG_TX_FORMAT; DUPLICCATE_SET_CODE - set code is duplicated unexpectedly; UNKNOWN_ERROR
messagestringa message descripting status_code
returnsrepeated stringreturn values for each Action
receiptsrepeated Receiptfor event functions

Receipt

KeyTypeDescription
func_namestringABI function name
contentstringcontent

/getTxReceiptByTxHash/{hash}

GET

Get transaction receipt data with transaction hash.

Request

A request may look like this:

curl http://127.0.0.1:30001/getTxReceiptByTxHash/6eGkZoXPQtYXdh7dBSXe2L1ckUCDj4egRn4fXtS2ACnR
KeyTypeDescription
hashstringhash of the receipt

Response

A successful response may look like this:

200 OK

{
    "tx_hash": "6eGkZoXPQtYXdh7dBSXe2L1ckUCDj4egRn4fXtS2ACnR",
    "gas_usage": 6633,
    "ram_usage": {
        "admin": "0",
        "issue.aiou": "0"
    },
    "status_code": "SUCCESS",
    "message": "",
    "returns": ["[\"\"]"],
    "receipts": [{
        "func_name": "token.aiou/transfer",
        "content": "[\"aiou\",\"admin\",\"i1544269477\",\"1\",\"\"]"
    }]
}
KeyTypeDescription
TxReceiptreceipt of the transaction

/getBlockByHash/{hash}/{complete}

GET

Get block information with block hash.

Request

A request may look like this:

curl http://127.0.0.1:30001/getBlockByHash/4c9GHyGLi6hUqB4d6zGFcywycYKucsmWsbgvhPe31GaY/false
KeyTypeDescription
hashstringblock hash
completebooltrue - show detailed transactions within the block; false - don't.

Response

A successful response may look like this:

200 OK

{
    "status": "IRREVERSIBLE",
    "block": {
        "hash": "4c9GHyGLi6hUqB4d6zGFcywycYKucsmWsbgvhPe31GaY",
        "version": "0",
        "parent_hash": "G4njPLnYskU4DcuTz5CwpLPETcfH6yN78V8emge8t21f",
        "tx_merkle_hash": "HHKAG2D7Kon2on5SqV66ZsfdNk9Wus8yhWqdTb86wgPJ",
        "tx_receipt_merkle_hash": "FXr8Mf7hr568MP23BFWJiBUej2xSj3M7416WAKJpswzx",
        "number": "2",
        "witness": "AIOU2YKPmRDGy5xLR7Gv65CN5nQ3vMmVhRjAsEM7Gj9xcB1LWgZUAd",
        "time": "1544262978309033000",
        "gas_usage": 0,
        "tx_count": "1",
        "info": null,
        "transactions": []
    }
}
KeyTypeDescription
statusenumPENDING - block is in cache; IRREVERSIBLE - block is irreversible.
blockBlocka Block struct

Block

KeyTypeDescription
hashstringblock hash
versionint64block version number
parent_hashstringthe hash of the parent block of this block
tx_merkle_hashstringthe merkle tree hash of all transactions
tx_receipt_merkle_hashstringthe merkle tree hash of all receipts
numberint64block number
witnessstringpublic key of the block producer
timeint64time of block production
gas_usagedoubletotal GAS consumption within the block
tx_countint64transaction number in the block
infoInfo(This key is reserved.)
transactionsrepeated Transactionall the transactions.

Info

KeyTypeDescription
modeint32mode of concurrency; 0 - non-concurrent; 1 - concurrent
threadint32the thread count of transaction concurrent execution
batch_indexrepeated int32indices of the transaction

/getBlockByNumber/{number}/{complete}

GET

Get block information using the block number.

Request

A request may look like this:

curl http://127.0.0.1:30001/getBlockByNumber/3/false
KeyTypeDescription
numberint64block number
completebooltrue - display transactions of the block; false - don't.

Response

A successful response may look like this:

200 OK

{
    "status": "IRREVERSIBLE",
    "block": {
        "hash": "HPZyoPQ44vsyLDRspjgrySyHnpuiGwckPx8uNtHZugJW",
        "version": "0",
        "parent_hash": "4c9GHyGLi6hUqB4d6zGFcywycYKucsmWsbgvhPe31GaY",
        "tx_merkle_hash": "HHKAG2D7Kon2on5SqV66ZsfdNk9Wus8yhWqdTb86wgPJ",
        "tx_receipt_merkle_hash": "62pESNUGDVsH4B1BCymJvmjGxPu5bb4R3u4x45K9Ybdq",
        "number": "3",
        "witness": "AIOU2YKPmRDGy5xLR7Gv65CN5nQ3vMmVhRjAsEM7Gj9xcB1LWgZUAd",
        "time": "1544262978609003000",
        "gas_usage": 0,
        "tx_count": "1",
        "info": null,
        "transactions": []
    }
}
KeyTypeDescription
statusenumPENDING - block is in cache; IRREVERSIBLE - block is not reversible
blockBlockthe block struct

/getAccount/{name}/{by_longest_chain}

GET

Get account information.

Request

A request may look like this:

curl http://127.0.0.1:30001/getAccount/admin/true
KeyTypeDescription
namestringthe account name
by_longest_chainbooltrue - get data from the longest chain; false - get data from irreversible blocks

Response

A successful response may look like this:

200 OK

{
    "name": "admin",
    "balance": 982678652,
    "gas_info": {
        "current_total": 53102598634,
        "transferable_gas": 60000,
        "pledge_gas": 53102538634,
        "increase_speed": 330011,
        "limit": 90003000000,
        "pledged_info": [{
            "pledger": "admin",
            "amount": 3000100
        }]
    },
    "ram_info": {
        "available": "99000"
    },
    "permissions": {
        "active": {
            "name": "active",
            "group_names": [],
            "items": [{
                "id": "AIOU2mCzj85xkSvMf1eoGtrexQcwE6gK8z5xr6Kc48DwxXPCqQJva4",
                "is_key_pair": true,
                "weight": "1",
                "permission": ""
            }],
            "threshold": "1"
        },
        "owner": {
            "name": "owner",
            "group_names": [],
            "items": [{
                "id": "AIOU2mCzj85xkSvMf1eoGtrexQcwE6gK8z5xr6Kc48DwxXPCqQJva4",
                "is_key_pair": true,
                "weight": "1",
                "permission": ""
            }],
            "threshold": "1"
        }
    },
    "groups": {},
    "frozen_balances": [],
    "vote_infos": []
}
KeyTypeDescription
namestringaccount name
balancedoublethe balance of the account
gas_infoGasInfoGas information
ram_infoRAMInfoRam information
permissionsmap<string, Permission>permissions
groupsmap<string, Group>permission groups
frozen_balancesrepeated FrozenBalanceinformation on the frozen balance
vote_infosrepeated VoteInfoinformation of vote

GasInfo

KeyTypeDescription
current_totaldoubleTotal gas for the moment
transferable_gasdoubleGas available for trade
pledge_gasdoubleGas obtained from deposits
increase_speeddoubleThe rate of gas increase, in gas per second
limitdoubleThe upper limit of gas from token deposit
pledged_inforepeated PledgeInfoThe information on deposit made by other accounts, on behalf of the inquired account

PledgeInfo

KeyTypeDescription
pledgerstringthe account receiving the deposit
amountdoublethe amount of the deposit

RAMInfo

KeyTypeDescription
availableint64RAM bytes available for use
usedint64RAM bytes used
totalint64RAM bytes total

Permission

KeyTypeDescription
namestringpermission name
group_namesrepeated stringpermission group names
itemsrepeated Itempermission information
thresholdint64permission threshold

Item

KeyTypeDescription
idstringpermission name or key paid ID
is_key_pairbooltrue - id is a key pair; false - id is a permission name
weightint64permission weight
permissionstringthe permission

Group

KeyTypeDescription
namestringname of the group
itemsrepeated Iteminformation on the permission group

FrozenBalance

KeyTypeDescription
amountdoublethe amount
timeint64the time when the amount is unfrozen

VoteInfo

KeyTypeDescription
optionstringcandidate
votesstringnumber of votes
cleared_votesstringnumber of votes cleared

/getTokenBalance/{account}/{token}/{by_longest_chain}

GET

Get account balance of a specified token.

Request

A request may look like this:

curl http://127.0.0.1:30001/getTokenBalance/admin/aiou/true
KeyTypeDescription
accountstringaccount name
tokenstringtoken name
by_longest_chainbooltrue - get information from the longest chain; false - get data from irreversible blocks

Response

A successful response may look like this:

200 OK

{
    "balance": 982678652,
    "frozen_balances": []
}
KeyTypeDescription
balancedoublethe balance
frozen_balancesrepeated FrozenBalancethe information on frozen balance

/GetProducerVoteInfo/{name}/{by_longest_chain}

GET

Get producer vote infomation

Request

A request may look like this:

curl http://127.0.0.1:30001/getProducerVoteInfo/producerName/true
KeyTypeDescription
idstringproducer Name
by_longest_chainbooltrue - get data from longest chain; false - get data from irreversible blocks

Response

A successful response may look like this:

{
    pubkey: "9V1v7Emef8MyPc1uBc9i5BmrTFxpUkxvQa1vUUSuzr4F",
    loc: "",
    url: "",
    net_id: "12D3KooWMQnia3aw9Yp7yrbeMB8KhTWYxaSdbNf6FBketXJs4n76",
    is_producer: true,
    status: "APPROVED",
    online: true,
    votes: 2100000,
}

/getContract/{id}/{by_longest_chain}

GET

Get contract information using contract ID.

Request

A request may look like this:

curl http://127.0.0.1:30001/getContract/base.aiou/true
KeyTypeDescription
idstringcontract ID
by_longest_chainbooltrue - get data from longest chain; false - get data from irreversible blocks

Response

A successful response may look like this:

200 OK

{
    "id": "base.aiou",
    "code": "const producerPermission = 'active';\nconst voteStatInterval = 200;\nclass Base {\n    constructor() {\n    }\n    init() {\n        _AIOUInstruction_counter.incr(12);this._put('execBlockNumber', 0);\n    }\n    InitAdmin(adminID) {\n        _AIOUInstruction_counter.incr(4);const bn = block.number;\n        if (_AIOUInstruction_counter.incr(8),_AIOUBinaryOp(bn, 0, '!==')) {\n            _AIOUInstruction_counter.incr(14);throw new Error('init out of genesis block');\n        }\n        _AIOUInstruction_counter.incr(12);this._put('adminID', adminID);\n    }\n    can_update(data) {\n        _AIOUInstruction_counter.incr(12);const admin = this._get('adminID');\n        _AIOUInstruction_counter.incr(12);this._requireAuth(admin, producerPermission);\n        return true;\n    }\n    _requireAuth(account, permission) {\n        _AIOUInstruction_counter.incr(12);const ret = BlockChain.requireAuth(account, permission);\n        if (_AIOUInstruction_counter.incr(8),_AIOUBinaryOp(ret, true, '!==')) {\n            _AIOUInstruction_counter.incr(22);throw new Error(_AIOUBinaryOp('require auth failed. ret = ', ret, '+'));\n        }\n    }\n    _get(k) {\n        _AIOUInstruction_counter.incr(12);const val = storage.get(k);\n        if (_AIOUInstruction_counter.incr(8),_AIOUBinaryOp(val, '', '===')) {\n            return null;\n        }\n        _AIOUInstruction_counter.incr(12);return JSON.parse(val);\n    }\n    _put(k, v) {\n        _AIOUInstruction_counter.incr(24);storage.put(k, JSON.stringify(v));\n    }\n    _vote() {\n        _AIOUInstruction_counter.incr(12);BlockChain.callWithAuth('vote_producer.aiou', 'Stat', `[]`);\n    }\n    _bonus(data) {\n        _AIOUInstruction_counter.incr(24);BlockChain.callWithAuth('bonus.aiou', 'IssueContribute', JSON.stringify([data]));\n    }\n    _saveBlockInfo() {\n        _AIOUInstruction_counter.incr(12);let json = storage.get('current_block_info');\n        _AIOUInstruction_counter.incr(36);storage.put(_AIOUBinaryOp('chain_info_', block.parentHash, '+'), JSON.stringify(json));\n        _AIOUInstruction_counter.incr(24);storage.put('current_block_info', JSON.stringify(block));\n    }\n    Exec(data) {\n        _AIOUInstruction_counter.incr(12);this._saveBlockInfo();\n        _AIOUInstruction_counter.incr(4);const bn = block.number;\n        _AIOUInstruction_counter.incr(12);const execBlockNumber = this._get('execBlockNumber');\n        if (_AIOUInstruction_counter.incr(8),_AIOUBinaryOp(bn, execBlockNumber, '===')) {\n            return true;\n        }\n        _AIOUInstruction_counter.incr(12);this._put('execBlockNumber', bn);\n        if (_AIOUInstruction_counter.incr(16),_AIOUBinaryOp(_AIOUBinaryOp(bn, voteStatInterval, '%'), 0, '===')) {\n            _AIOUInstruction_counter.incr(12);this._vote();\n        }\n        _AIOUInstruction_counter.incr(12);this._bonus(data);\n    }\n}\n_AIOUInstruction_counter.incr(7);module.exports = Base;",
    "language": "javascript",
    "version": "1.0.0",
    "abis": [{
        "name": "Exec",
        "args": ["json"],
        "amount_limit": []
    }, {
        "name": "can_update",
        "args": ["string"],
        "amount_limit": []
    }, {
        "name": "InitAdmin",
        "args": ["string"],
        "amount_limit": []
    }, {
        "name": "init",
        "args": [],
        "amount_limit": []
    }]
}
KeyTypeDescription
idstringcontract ID
codestringthe code of the contract
languagestringthe language of the contract
versionstringcontract version
abisrepeated ABIthe ABIs of the contract

ABI

KeyTypeDescription
namestringinterface name
argsrepeated stringarguments of the interface
amount_limitrepeated AmountLimitThe limits on the amount

/getContractStorage

POST

Get contract storage data.

Request

A request may look like this:

curl -X POST http://127.0.0.1:30001/getContractStorage -d '{"id":"token.aiou","key":"TIaiou","field":"decimal","by_longest_chain":true}'
KeyTypeDescription
idstringID of the smart contract
keystringthe key of StateDB
fieldstringthe values from StateDB; if StateDB[key] is a map then it is required to configure field to obtain values of StateDB[key][field]
by_longest_chainbooltrue - get data from the longest chain; false - get data from irreversible blocks

Response

A successful response may look like this:

200 OK
{"data":"8","block_hash":"GFfWHwe9cdw5aHaTDExFm2DBzaV9wdgybTQpHsQsbaKS","block_number":"38194"}
KeyTypeDescription
datastringthe stored data
block_hashstringthe hash of block from which the data is from
block_numberstringthe number of block from which the data is from

/getContractStorageFields

POST

Get contract storage key list of map, up to 256 are returned.
Note: Developers should not rely on this API to obtain all keys of a map in the contract. If there is such a requirement, you need to maintain all keys yourself .

Request

A request may look like this:

curl -X POST http://127.0.0.1:30001/getContractStorageFields -d '{"id":"token.aiou","key":"TIaiou","by_longest_chain":true}'
KeyTypeDescription
idstringID of the smart contract
keystringthe key of StateDB
by_longest_chainbooltrue - get data from the longest chain; false - get data from irreversible blocks

Response

A successful response may look like this:

200 OK
{
    "fields": ["issuer","totalSupply","supply","canTransfer","onlyIssuerCanTransfer","defaultRate","decimal","fullName"]
}

/getBatchContractStorage


POST

Get batch contract storage data.

Request

A request may look like this:

curl -X POST http://127.0.0.1:30001/getBatchContractStorage -d '{"id":"token.aiou","key_fields":[{"field":"supply","key":"TIaiou"}, {"field":"decimal","key":"TIaiou"}, {"field":"xxxx","key":"xxxx"}],"by_longest_chain":true}'
KeyTypeDescription
idstringsmart contract ID
key_fieldsrepeated KeyFieldthe key-fields which are queried,the order of return values is the same as the request
by_longest_chainbooltrue - get data from the longest chain; false - get data from irreversible blocks

KeyField

KeyTypeDescription
keystringthe key of StateDB
fieldstringthe values from StateDB; if StateDB[key] is a map then it is required to configure field to obtain values of StateDB[key][field]

Response

A successful response may look like this:

200 OK
{"datas":["2100000000000000000","8","null"],"block_hash":"3Tv3QUPRhhAj7L3j6DCEtkKycXtkeFgAMU3zZU3HA6Qr","block_number":"39123"}
KeyTypeDescription
datasstringthe stored data, returned in order as request
block_hashstringthe hash of block from which the data is from
block_numberstringthe number of block from which the data is from

/sendTx

POST

Publish the transaction to the node. When the node receives the transaction, it will do a sanity check and return errors if the check fails. If the check passes, the transaction will be added to the transaction pool and return a Hash of the transaction.

Users may use the hash as an argument of the getTxByHash API or the getTxReceiptByTxHash API, to look up the transaction state, and check whether execution succeeds.

Notes:

This API requires transaction hash and signature, and is tricky to be called directly.

Developers may send transactions with JavaScript SDK.

Request Parameters

KeyTypeDescription
timeint64Time of the transaction generation, in nanoseconds, from UnixEpoch-zero.
expirationint64The time when the transaction expires, in nanoseconds since UnixEpoch-zero. If a block-producing node receives the transaction after expiration, it will not execute the transaction.
gas_ratiodoubleGAS ratio. This transaction will be executed with default ratio, multiplied by this parameter. The higher the ratio, the faster the transaction gets executed. The value can be reasonably between 1.0 to 100.0
gas_limitdoubleMaximum GAS allowed by this transaction. Should not be lower than 50,000
delayint64The nanoseconds of the transaction delay. Set to 0 for non-delayed transactions.
chain_iduint32chain_id
actionsrepeated ActionSpecific calls of the transaction
amount_limitrepeated AmountLimitLimits on token of the transaction. More than one token limits may be specified; if the transaction exceeds theses limits, execution will halt.
publisherstringID of the transaction publisher
publisher_sigsrepeated SignatureSignatures of the publisher, as described here. The publisher may provide multiple signatures for different permissions. Refer to documentations on the permission system.
signersrepeated stringThe IDs of signers other than the publisher. May be left empty.
signaturesrepeated SignatureSignatures of the signers. Each signers should have one or many signatures, so the length of the signatures should not be less than that of the signers.

Signature

KeyTypeDescription
algorithmstring"ED25519" or "SECP256K1"
signaturestringtransaction's signature
public_keystringThe public key corresponding to the signature

Response

KeyTypeDescription
hashstringthe transaction hash
pre_tx_receiptTxReceiptreceipt of transaction executed in advance by RPC node, returned only when RPC node opens the switch

Signing a transaction

There are three steps to sign a transaction: convert the transaction struct to byte array, calculate sha3 hash of the byte array, and sign this hash with your private key.

  • Convert transaction struct to byte array

    The algorithm is: convert each field of transaction into byte array in declarative order, and then add length before indefinite type (such as string and structure) and splice. The way the various field types are converted to byte arrays is shown in the table below.

    TypeConversion MethodExample
    intConvert to byte array with Big-endianint64(1023) is converted to [0 0 0 0 0 0 3 255]
    stringSplice the byte of each character in the string and add length before it"aiou" is converted to [0 0 0 4 105 111 115 116]
    arrayconvert each element of the array into a byte array, add length before each array, put them together["aiou" "aiou"] is converted to [0 0 0 2 0 0 0 4 105 111 115 116 0 0 0 4 105 111 115 116]
    mapEach pair of keys: values in the dictionary is converted into byte arrays and spliced, then each pair is spliced in ascending order of keys, and the length of map is added to the front of each pair.["b":"aiou", "a":"aiou"] converts to [0 0 0 2 0 0 0 1 97 0 0 0 4 105 111 115 116 0 0 0 1 98 0 0 0 4 105 111 115 116] "

    The transaction parameters are declared in this order: "time", "expiration", "gas_ratio", "gas_limit", "delay", "chain_id", "reserved", "signers", "actions", "amount_limit", and "signatures", so the pseudo-code converting a transaction struct to byte array is:

    func TxToBytes(t transaction) []byte {
            return Int64ToBytes(t.time) + Int64ToBytes(t. expiration) + 
                    Int64ToBytes(int64(t.gas_ratio * 100)) + Int64ToBytes(int64(t.gas_limit * 100)) +     // Node that gas_ratio and gas_limit need to be multiplied by 100 and convert to int64
                    Int64ToBytes(t.delay) + Int32ToBytes(t.chain_id) + 
                    BytesToBytes(t.reserved) + // reserved is a reserved field. It only needs to write an empty byte array when serialized. Don't send this field in RPC request parameters.
                    ArrayToBytes(t.signers) + ArrayToBytes(t.actions)  +
                    ArrayToBytes(t.amount_limit) + ArrayToBytes(t.signatures)
        }
    

    Refer to go-aiou for golang implementation; refer to aiou.js for JavaScript implementation.

  • Calculate the hash of the byte array with sha3 algorithm

    Use the sha3 libraries in your language to calculate hash of the byte array you obtained from the previous step.

  • Sign the hash with private key

    AIOU supports two asymmetric encryption algorithms: Ed25519 and Secp256k1. These two algorithms share the same signing process: generate a public-private key pair, and sign the hash from the previous step.

    The private key of the "publisher_sigs" must agree with the transaction's "publisher" account. The "signatures" private keys must agrees with the transaction's "signers" accounts. "signatures" is used for multi-layer signing, and is not required; "publisher_sigs" is required. Fees for transaction execution will be taken out from the publisher's account.

Request example

Assume account "testaccount" has a transaction that transfers 100 aiou to the account named "anothertest".

  • Construct the transaction

    {
        "time": 1544709662543340000,
        "expiration": 1544709692318715000,
        "gas_ratio": 1,
        "gas_limit": 500000,
        "delay": 0,
        "chain_id": 1024,
        "signers": [],
        "actions": [
            {
                "contract": "token.aiou",
                "action_name": "transfer",
                "data": "[\"aiou\", \"testaccount\", \"anothertest\", \"100\", \"this is an example transfer\"]",
            },
        ],
        "amount_limit": [
            {
                "token": "*",
                "value": "unlimited",
            },
        ],
        "signatures": [],
    }
    
  • Calculate hash

    After serializing and hashing the transaction, we obtain the hash "/gB8TJQibGI7Kem1v4vJPcJ7vHP48GuShYfd/7NhZ3w=".

  • Calculate signature

    Assume "testaccount" has a public key with ED25519 algorithm, the public key is "lDS+SdM+aiVHbDyXapvrsgyKxFg9mJuHWPZb/INBRWY=", and the private key is "gkpobuI3gbFGstgfdymLBQAGR67ulguDzNmLXEJSWaGUNL5J0z5qJUdsPJdqm+uyDIrEWD2Ym4dY9lv8g0FFZg==". Sign the hash with the private key and we get "/K1HM0OEbfJ4+D3BmalpLmb03WS7BeCz4nVHBNbDrx3/A31aN2RJNxyEKhv+VSoWctfevDNRnL1kadRVxSt8CA=="

  • Publish transaction

    The complete transaction parameter is:

    {
        "time": 1544709662543340000,
        "expiration": 1544709692318715000,
        "gas_ratio": 1,
        "gas_limit": 500000,
        "delay": 0,
        "chain_id": 1024,
        "signers": [],
        "actions": [
            {
                "contract": "token.aiou",
                "action_name": "transfer",
                "data": "[\"aiou\", \"testaccount\", \"anothertest\", \"100\", \"this is an example transfer\"]",
            },
        ],
        "amount_limit": [
            {
                "token": "*",
                "value": "unlimited",
            },
        ],
        "signatures": [],
        "publisher": "testaccount",
        "publisher_sigs": [
            {
                "algorithm": "ED25519",
                "public_key": "lDS+SdM+aiVHbDyXapvrsgyKxFg9mJuHWPZb/INBRWY=",
                "signature": "/K1HM0OEbfJ4+D3BmalpLmb03WS7BeCz4nVHBNbDrx3/A31aN2RJNxyEKhv+VSoWctfevDNRnL1kadRVxSt8CA==",
            },
        ],
    }
    

    After we JSON-serialize the struct, we can send the following RPC:

    curl -X POST http://127.0.0.1:30001/sendTx -d '{"actions":[{"action_name":"transfer","contract":"token.aiou","data":"[\"aiou\", \"testaccount\", \"anothertest\", \"100\", \"this is an example transfer\"]"}],"amount_limit":[{"token":"*","value":"unlimited"}],"delay":0,"chain_id":1024, "expiration": 1544709692318715000,"gas_limit":500000,"gas_ratio":1,"publisher":"testaccount","publisher_sigs":[{"algorithm":"ED25519","public_key":"lDS+SdM+aiVHbDyXapvrsgyKxFg9mJuHWPZb/INBRWY=","signature":"/K1HM0OEbfJ4+D3BmalpLmb03WS7BeCz4nVHBNbDrx3/A31aN2RJNxyEKhv+VSoWctfevDNRnL1kadRVxSt8CA=="}],"signatures":[],"signers":[],"time": 1544709662543340000}'
    

/execTx

POST

Send the transaction to the node, and execute immediately. This will not seek consensus on the chain, nor will this transaction persist.

This API is used to check whether a testing contract executes as expected. Obviously, execTx cannot guarantee the same behaviour with an on-chain execution due to different time to call.

Request

This API shares the same set of paramters with /sendTx.

Response

This API shares the same response format with /getTxReceiptByTxHash.

/subscribe

POST

Subscription events, including events triggered in smart contracts and transactions completed.

Request

A request may look like this:

curl -X POST http://127.0.0.1:30001/subscribe -d '{"topics":["CONTRACT_RECEIPT"], "filter":{"contract_id":"token.aiou"}}'
KeyTypeDescription
topicsrepeated enumtopics,the enum is CONTRACT_EVENT or CONTRACT_RECEIPT
filterFilterReceived events are filtered according to the fields in the filter. If this field is not passed, event data in all topics will be received.

Filter

KeyTypeDescription
contract_idstringcontract id

Response

A successful response may look like this:

{"result":{"event":{"topic":"CONTRACT_RECEIPT","data":"[\"contribute\",\"producer00001\",\"900\"]","time":"1545646637413936000"}}}
{"result":{"event":{"topic":"CONTRACT_RECEIPT","data":"[\"contribute\",\"producer00001\",\"900\"]","time":"1545646637711757000"}}}
{"result":{"event":{"topic":"CONTRACT_RECEIPT","data":"[\"contribute\",\"producer00001\",\"900\"]","time":"1545646638013188000"}}}
{"result":{"event":{"topic":"CONTRACT_RECEIPT","data":"[\"contribute\",\"producer00001\",\"900\"]","time":"1545646638317840000"}}}
...
KeyTypeDescription
topicenumtopic,the enum is CONTRACT_EVENT or CONTRACT_RECEIPT
datastringevent data
timeint64event timestamp

/getCandidateBonus/{name}/{by_longest_chain}


GET

概要: Query the voting bonus a node can receive.

Request

A request may look like this:

curl http://127.0.0.1:30001/getCandidateBonus/erebus/1
KeyTypeDescription
namestringnode account name
by_longest_chainbooltrue - get data from the longest chain; false - get data from irreversible blocks

Response

A successful response may look like this:

200 OK
{
    "bonus": 111866.61819617
}
KeyTypeDescription
bonusdoublethe bonus he can receive

/getVoterBonus/{name}/{by_longest_chain}


GET

概要: Query the voting bonus a voter can receive.

Request

A request may look like this:

curl http://127.0.0.1:30001/getVoterBonus/admin/1
KeyTypeDescription
namestringvoter account name
by_longest_chainbooltrue - get data from the longest chain; false - get data from irreversible blocks

Response

A successful response may look like this:

200 OK
{
    "bonus": 94875.58356478,
    "detail":
    {
        "dapppub": 15414.37339835,
        "aiouamerica": 17212.96477434,
        "laomao": 9895.73931972,
        "metanyx": 29877.55014659,
        "sutler": 20924.99488913,
        "tokenpocket": 1549.96103665
    }
}
KeyTypeDescription
bonusdoublethe total voting bonus he can receive
detailmap<string, double>the bonus from every candidate

/getTokenInfo/{symbol}/{by_longest_chain}


GET

概要: Query the token information.

Request

A request may look like this:

curl http://127.0.0.1:30001/getTokenInfo/aiou/1
KeyTypeDescription
symbolstringtoken symbol
by_longest_chainbooltrue - get data from the longest chain; false - get data from irreversible blocks

Response

A successful response may look like this:

200 OK
{
    "symbol": "aiou",
    "full_name": "aiou",
    "issuer": "issue.aiou",
    "total_supply": "9000000000000000000",
    "current_supply": "2100000000000000000",
    "decimal": 8,
    "can_transfer": true,
    "only_issuer_can_transfer": false,
    "total_supply_float": 90000000000,
    "current_supply_float": 21000000000
}
KeyTypeDescription
symbolstringtoken symbol
full_namestringtoken full name
issuerstringtoken issuer
total_supplystringtotal amount of token supply, is the result of total_supply_float multiplied by decimal
current_supplystringcurrent amount of token supply, is the result of current_supply_float multiplied by decimal
total_supply_floatdoubletotal amount of token supply
current_supply_floatdoublecurrent amount of token supply
decimalinttoken decimal
can_transferboolwhether the token can be transfered
only_issuer_can_transferboolwhether the token can only be transfered by issuer
← Become Servi NodeSystem Contract →
  • /getNodeInfo
    • Request
    • Response
    • NetworkInfo
  • /getChainInfo
    • Request
    • Response
  • /getGasRatio
    • Request
    • Response
  • /getRAMInfo
    • Request
    • Response
  • /getTxByHash
    • Request
    • Response
    • Transaction
    • Action
    • AmountLimit
    • TxReceipt
    • Receipt
  • /getTxReceiptByTxHash/{hash}
    • Request
    • Response
  • /getBlockByHash/{hash}/{complete}
    • Request
    • Response
    • Block
    • Info
  • /getBlockByNumber/{number}/{complete}
    • Request
    • Response
  • /getAccount/{name}/{by_longest_chain}
    • Request
    • Response
    • GasInfo
    • PledgeInfo
    • RAMInfo
    • Permission
    • Item
    • Group
    • FrozenBalance
    • VoteInfo
  • /getTokenBalance/{account}/{token}/{by_longest_chain}
    • Request
    • Response
  • /GetProducerVoteInfo/{name}/{by_longest_chain}
    • Request
    • Response
  • /getContract/{id}/{by_longest_chain}
    • Request
    • Response
    • ABI
  • /getContractStorage
    • Request
    • Response
  • /getContractStorageFields
    • Request
    • Response
  • /getBatchContractStorage
    • Request
    • KeyField
    • Response
  • /sendTx
    • Request Parameters
    • Signature
    • Response
    • Signing a transaction
    • Request example
  • /execTx
    • Request
    • Response
  • /subscribe
    • Request
    • Filter
    • Response
  • /getCandidateBonus/{name}/{by_longest_chain}
    • Request
    • Response
  • /getVoterBonus/{name}/{by_longest_chain}
    • Request
    • Response
  • /getTokenInfo/{symbol}/{by_longest_chain}
    • Request
    • Response
AIOU Chain Docs
Community
BlogGitHubStar
Facebook Open Source
Copyright © 2021 Your Name or Your Company Name