Contract Functionality
This section will illustrate the API calls for querying the following information:
- available compilers
- current energy price
- energy estimate
- contract code
- contract storage
and performing the following actions:
- compile Solidity code
- deploy a contract
- execute a contract function
- call a contract function
The final subsection contains code illustrating all of the above interactions.
Retrieve Available Compilers
The JavaScript example below shows how to query the APIs for the list of available code compilers.
The functionality is compatible with eth_getCompilers
.
Only the Solidity compiler is currently supported.
The Aion blockchain currently does not support:
// get list of available compilers
let compilers = web3.eth.getCompilers();
// print
console.log("available compilers:");
console.log(compilers);
Sample output:
available compilers:
[ 'solidity' ]
Compile Solidity Code
The examples below show how to use the APIs to compile solidity code.
The functionality is compatible with eth_compileSolidity
.
In each code snippet, the given contract is compiled and the output is printed to the standard output.
// contract source code
String source_ticker = "contract ticker { uint public val; function tick () { val+= 1; } }";
// compile code
Map<String, CompileResponse> result = api.getTx().compile(source_ticker).getObject();
// print result
System.out.println(result);
// contract source code
const source_ticker = 'contract ticker { uint public val; function tick () { val+= 1; } }';
// compile code
let result = web3.eth.compile.solidity(source_ticker);
// print result
console.log(result);
Sample output:
{ticker=code :0x605060405234156100105760006000fd5b610015565b60c2806100236000396000f30060506040526000356c01000000000000000000000000900463ffffffff1680633c6bb43614603b5780633eaf5d9f146062576035565b60006000fd5b341560465760006000fd5b604c6075565b6040518082815260100191505060405180910390f35b3415606d5760006000fd5b6073607e565b005b60006000505481565b6001600060008282825054019250508190909055505b5600a165627a7a723058201c1817d957da90680b7c55720aff16e7a4407b31f7480f63210748a5cc4efb0c0029,
source :contract ticker { uint public val; function tick () { val+= 1; } },
language :,
languageVersion: ,
compilerVersion: ,
compilerOption: ,
abiDefString: [{"outputs":[{"name":"","type":"uint128"}],"constant":true,"payable":false,"inputs":[],"name":"val","type":"function"},{"outputs":[],"constant":false,"payable":false,"inputs":[],"name":"tick","type":"function"}],
abiDefinition:
[
constant: true,
anonymous: false,
payable: false,
type: function,
name: val,
inputs:
outputs:
[
indexed: false,
type: uint128,
name: ,
paramLengths:
[
]
]
isEvent: false,
isConstructor: false,
isFallback: false,
hashed: 3c6bb436
],
[
constant: false,
anonymous: false,
payable: false,
type: function,
name: tick,
inputs:
outputs:
isEvent: false,
isConstructor: false,
isFallback: false,
hashed: 3eaf5d9f
]
userDoc: constant: false,
name: ,
type: ,
inputs:
outputs:
,
developerDocconstant: false,
name: ,
type: ,
inputs:
outputs:
}
{ ticker:
{ code: '0x605060405234156100105760006000fd5b610015565b60c2806100236000396000f30060506040526000356c01000000000000000000000000900463ffffffff1680633c6bb43614603b5780633eaf5d9f146062576035565b60006000fd5b341560465760006000fd5b604c6075565b6040518082815260100191505060405180910390f35b3415606d5760006000fd5b6073607e565b005b60006000505481565b6001600060008282825054019250508190909055505b5600a165627a7a723058201c1817d957da90680b7c55720aff16e7a4407b31f7480f63210748a5cc4efb0c0029',
info:
{ abiDefinition: [Array],
languageVersion: '0',
language: 'Solidity',
compilerVersion: '0.4.15+commit.ecf81ee5.Linux.g++',
source: 'contract ticker { uint public val; function tick () { val+= 1; } }' } } }
Retrieve Energy Price
The examples below show how to query the APIs for the current price per NRG in nAmp.
The functionality is compatible with eth_gasPrice
.
In each code snippet, the NRG price is retrieved from the API and printed to the standard output.
// get NRG price
long price = api.getTx().getNrgPrice().getObject();
// print price
System.out.println("current NRG price = " + price + " nAmp");
// get NRG price
let price = web3.eth.gasPrice
// print price
console.log("current NRG price = " + price + " nAmp");
Sample output:
current NRG price = 10000000000 nAmp
current NRG price = 10000000000 nAmp
Estimate Energy Required
The examples below show how to use the APIs to estimate the NRG required to allow the transaction to complete.
The functionality is compatible with eth_estimateGas
.
In each code snippet, the NRG estimate is retrieved from the API and printed to the standard output.
// compile contract source code
String source_ticker = "contract ticker { uint public val; function tick () { val+= 1; } }";
Map<String, CompileResponse> result = api.getTx().compile(source_ticker).getObject();
// get NRG estimate for contract
long estimate = api.getTx().estimateNrg(result.get("ticker").getCode()).getObject();
// print estimate
System.out.println("NRG estimate for contract = " + estimate + " NRG");
// transaction data
Address sender = Address.wrap("a06f02e986965ddd3398c4de87e3708072ad58d96e9c53e87c31c8c970b211e5");
Address receiver = Address.wrap("a0bd0ef93902d9e123521a67bef7391e9487e963b2346ef3b3ff78208835545e");
BigInteger amount = BigInteger.valueOf(1_000_000_000_000_000_000L); // = 1 AION
ByteArrayWrapper data = ByteArrayWrapper.wrap("test.message".getBytes());
// prepare transaction
TxArgs tx = new TxArgs.TxArgsBuilder().data(data).from(sender).to(receiver).value(amount).createTxArgs();
// get NRG estimate for transaction
estimate = api.getTx().estimateNrg(tx).getObject();
// print estimate
System.out.println("NRG estimate for transaction = " + estimate + " NRG");
// compile contract source code
const source_ticker = 'contract ticker { uint public val; function tick () { val+= 1; } }';
let result = web3.eth.compile.solidity(source_ticker);
// get NRG estimate for contract
let estimate = web3.eth.estimateGas({data:result.ticker.code});
// print estimate
console.log("NRG estimate for contract = " + estimate + " NRG");
// transaction data
let sender = 'a06f02e986965ddd3398c4de87e3708072ad58d96e9c53e87c31c8c970b211e5';
let receiver = 'a0bd0ef93902d9e123521a67bef7391e9487e963b2346ef3b3ff78208835545e';
let amount = 1000000000000000000; // = 1 AION
let data = '0x746573742e6d657373616765'; // hex for "test.message"
// get NRG estimate for transaction
estimate = web3.eth.estimateGas({data: data, from: sender, to: receiver, value: amount})
// print estimate
console.log("NRG estimate for transaction = " + estimate + " NRG");
Sample output:
NRG estimate for contract = 233661 NRG
NRG estimate for transaction = 21768 NRG
NRG estimate for contract = 233661 NRG
NRG estimate for transaction = 21768 NRG
Retrieve Contract Code
The examples below show how to use the APIs to retrieve the code for a contract.
The functionality is compatible with eth_getCode
. In each code snippet, the contract code is retrieved from the API and printed to the standard output.
// set contract account
Address contractAccount = Address.wrap("a0960fcb7d6423a0446243916c7c6360543b3d2f9c5e1c5ff7badb472b782b79");
// get code from latest block
long blockNumber = -1L; // indicates latest block
byte[] code = api.getTx().getCode(contractAccount, blockNumber).getObject();
// print code
System.out.println("0x" + IUtils.bytes2Hex(code));
// set contract account
let ctAcc = 'a0960fcb7d6423a0446243916c7c6360543b3d2f9c5e1c5ff7badb472b782b79';
// get code from latest block
let code = web3.eth.getCode(ctAcc, 'latest');
// print code
console.log(code);
Sample output:
0x60506040526000356c01000000000000000000000000900463ffffffff1680630fd5f53f146100545780634985e85c146100e25780638da5cb5b1461015f578063ceb35b0f146101905761004e565b60006000fd5b34156100605760006000fd5b6100e06004808035906010019082018035906010019191908080600f01601080910402601001604051908101604052809392919081815260100183838082843782019150505050505090909190808060100135903590916020019091929080356effffffffffffffffffffffffffffff1916906010019091905050610203565b005b34156100ee5760006000fd5b6101426004808035906010019082018035906010019191908080600f0160108091040260100160405190810160405280939291908181526010018383808284378201915050505050509090919050506103af565b604051808383825281601001526020019250505060405180910390f35b341561016b5760006000fd5b610173610457565b604051808383825281601001526020019250505060405180910390f35b341561019c5760006000fd5b6102016004808035906010019082018035906010019191908080600f0160108091040260100160405190810160405280939291908181526010018383808284378201915050505050509090919080806010013590359091602001909192905050610466565b005b600060005080600101549054339091149190141615156102235760006000fd5b828260026000506000876040518082805190601001908083835b60108310151561026357805182525b60108201915060108101905060108303925061023d565b6001836010036101000a03801982511681845116808217855250505050505090500191505060405180910390209060001916909060001916908252816010015260200190815260100160002090506000508282909180600101839055555050508060036000506000858582528160100152602001908152601001600020905060006101000a81548160ff02191690836f01000000000000000000000000000000900402179055507fdb8f9fd4bfba5ae615ae02e8b4d281b887225fd3d34a5ac7b8d78df768bb63e7856040518080601001828103825283818151815260100191508051906010019080838360005b8381101561036d5780820151818401525b601081019050610351565b50505050905090810190600f16801561039a5780820380516001836010036101000a031916815260100191505b509250505060405180910390a15b5b50505050565b6000600060026000506000846040518082805190601001908083835b6010831015156103f157805182525b6010820191506010810190506010830392506103cb565b6001836010036101000a03801982511681845116808217855250505050505090500191505060405180910390209060001916909060001916908252816010015260200190815260100160002090506000508060010154905491509150610452565b915091565b60006000508060010154905482565b600060005080600101549054339091149190141615156104865760006000fd5b818160026000506000866040518082805190601001908083835b6010831015156104c657805182525b6010820191506010810190506010830392506104a0565b6001836010036101000a038019825116818451168082178552505050505050905001915050604051809103902090600019169090600019169082528160100152602001908152601001600020905060005082829091806001018390555550505081817fa226db3f664042183ee0281230bba26cbf7b5057e50aee7f25a175ff45ce4d7f60405160405180910390a25b5b5050505600a165627a7a723058201a36e96ba95136c7bf35a644bf8d3382c49dafc64e9362b025ed6f4eb99ed0640029
0x60506040526000356c01000000000000000000000000900463ffffffff1680630fd5f53f146100545780634985e85c146100e25780638da5cb5b1461015f578063ceb35b0f146101905761004e565b60006000fd5b34156100605760006000fd5b6100e06004808035906010019082018035906010019191908080600f01601080910402601001604051908101604052809392919081815260100183838082843782019150505050505090909190808060100135903590916020019091929080356effffffffffffffffffffffffffffff1916906010019091905050610203565b005b34156100ee5760006000fd5b6101426004808035906010019082018035906010019191908080600f0160108091040260100160405190810160405280939291908181526010018383808284378201915050505050509090919050506103af565b604051808383825281601001526020019250505060405180910390f35b341561016b5760006000fd5b610173610457565b604051808383825281601001526020019250505060405180910390f35b341561019c5760006000fd5b6102016004808035906010019082018035906010019191908080600f0160108091040260100160405190810160405280939291908181526010018383808284378201915050505050509090919080806010013590359091602001909192905050610466565b005b600060005080600101549054339091149190141615156102235760006000fd5b828260026000506000876040518082805190601001908083835b60108310151561026357805182525b60108201915060108101905060108303925061023d565b6001836010036101000a03801982511681845116808217855250505050505090500191505060405180910390209060001916909060001916908252816010015260200190815260100160002090506000508282909180600101839055555050508060036000506000858582528160100152602001908152601001600020905060006101000a81548160ff02191690836f01000000000000000000000000000000900402179055507fdb8f9fd4bfba5ae615ae02e8b4d281b887225fd3d34a5ac7b8d78df768bb63e7856040518080601001828103825283818151815260100191508051906010019080838360005b8381101561036d5780820151818401525b601081019050610351565b50505050905090810190600f16801561039a5780820380516001836010036101000a031916815260100191505b509250505060405180910390a15b5b50505050565b6000600060026000506000846040518082805190601001908083835b6010831015156103f157805182525b6010820191506010810190506010830392506103cb565b6001836010036101000a03801982511681845116808217855250505050505090500191505060405180910390209060001916909060001916908252816010015260200190815260100160002090506000508060010154905491509150610452565b915091565b60006000508060010154905482565b600060005080600101549054339091149190141615156104865760006000fd5b818160026000506000866040518082805190601001908083835b6010831015156104c657805182525b6010820191506010810190506010830392506104a0565b6001836010036101000a038019825116818451168082178552505050505050905001915050604051809103902090600019169090600019169082528160100152602001908152601001600020905060005082829091806001018390555550505081817fa226db3f664042183ee0281230bba26cbf7b5057e50aee7f25a175ff45ce4d7f60405160405180910390a25b5b5050505600a165627a7a723058201a36e96ba95136c7bf35a644bf8d3382c49dafc64e9362b025ed6f4eb99ed0640029
Retrieve Stored Value
The examples below show how to use the APIs to retrieve stored values from a contract.
The functionality is compatible with eth_getStorageAt
.
In each code snippet, the stored values are retrieved from the API and printed to the standard output.
The contract for which the values are retrieved is personnel.sol which uses the first two values to store the owner address.
// view contract creation tx
Hash256 txHash = Hash256.wrap("0xb42a5f995450531f66e7db40efdfad2c310fa0f8dbca2a88c31fdc4837368e48");
TxReceipt receipt = api.getTx().getTxReceipt(txHash).getObject();
System.out.println(receipt);
// set contract account
Address contractAccount = receipt.getContractAddress();
// get value from storage
long blockNumber = -1L; // code for latest
String valuePos0 = api.getChain().getStorageAt(contractAccount, 0, blockNumber).getObject();
String valuePos1 = api.getChain().getStorageAt(contractAccount, 1, blockNumber).getObject();
// print values
// in this case the first two values are the contract owner
System.out.println("concatenated values = " + valuePos0 + valuePos1);
// view contract creation tx
let txHash = '0xb42a5f995450531f66e7db40efdfad2c310fa0f8dbca2a88c31fdc4837368e48';
let receipt = web3.eth.getTransactionReceipt(txHash);
console.log(receipt);
// set contract account
let contractAccount = receipt.contractAddress;
// get value from storage
let valuePos0 = web3.eth.getStorageAt(contractAccount, 0, 'latest');
let valuePos1 = web3.eth.getStorageAt(contractAccount, 1, 'latest');
// print values
// in this case the first two values are the contract owner
console.log("\nconcatenated values = " + valuePos0 + valuePos1);
Sample output:
txIndex: 0,
blockNumber: 298287,
nrg: 349674,
nrgCumulativeUsed: 349674,
blockHash: 0x2e9b90a21f9702fde90807e42db0107ce85b8c14a99c1f9f76182ec20599eebc,
txHash: 0xb42a5f995450531f66e7db40efdfad2c310fa0f8dbca2a88c31fdc4837368e48,
from: 0xa0bd0ef93902d9e123521a67bef7391e9487e963b2346ef3b3ff78208835545e,
to: 0x,
contractAddress: a076ddb4cf37f7cd1360de9cf2336f75f06c38655da09d4e3f9b690acf57c2e1,
log:
concatenated values = a0bd0ef93902d9e123521a67bef7391e9487e963b2346ef3b3ff78208835545e
{ blockHash: '0x2e9b90a21f9702fde90807e42db0107ce85b8c14a99c1f9f76182ec20599eebc',
nrgPrice: '0x02540be400',
logsBloom: '00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
nrgUsed: 349674,
contractAddress: '0xa076ddb4cf37f7cd1360de9cf2336f75f06c38655da09d4e3f9b690acf57c2e1',
transactionIndex: 0,
transactionHash: '0xb42a5f995450531f66e7db40efdfad2c310fa0f8dbca2a88c31fdc4837368e48',
gasLimit: '0x4c4b40',
cumulativeNrgUsed: 349674,
gasUsed: '0x0555ea',
blockNumber: 298287,
root: 'e433bbbc1714c2301faf7ac447c5881f345c32f8853e121694e430219cacb9d5',
cumulativeGasUsed: '0x555ea',
from: '0xa0bd0ef93902d9e123521a67bef7391e9487e963b2346ef3b3ff78208835545e',
to: '0x',
logs: [],
gasPrice: '0x02540be400',
status: '0x1' }
concatenated values = 0xa0bd0ef93902d9e123521a67bef7391e0x9487e963b2346ef3b3ff78208835545e
Deploy Contract
The examples below show how to use the APIs to deploy a contract.
In each code snippet, after deploying the contract the resulting account address, transaction hash and receipt are printed to the standard output.
Note that these examples only consider best case scenarios where the account can be unlocked, the transaction execution does not produce any errors and the transaction is eventually included in a block. A separate tutorial will be provided with the recommended sanity checks to ensure the deployed contract is included in the main chain.
// contract source code
String source_personnel =
"contract Personnel { address public owner; modifier onlyOwner() { require(msg.sender == owner); _;} "
+ "mapping(bytes32 => address) private userList; /** 3 LSB bits for each privilege type */ "
+ "mapping(address => bytes1) private userPrivilege; function Personnel(){ owner = msg.sender; } "
+ "event UserAdded(string _stamp); event AddressAdded(address indexed _addr); "
+ "function getUserAddress(string _stamp) constant returns (address){ return userList[sha3(_stamp)]; } "
+ "function addUser(string _stamp, address _addr, bytes1 _userPrivilege) "
+ "onlyOwner{ userList[sha3(_stamp)] = _addr; userPrivilege[_addr] = _userPrivilege; "
+ "UserAdded(_stamp); } function addAddress(string _stamp, address _addr) "
+ "onlyOwner{ userList[sha3(_stamp)] = _addr; AddressAdded(_addr); } }";
// compile code
Map<String, CompileResponse> result = api.getTx().compile(source_personnel).getObject();
CompileResponse contract = result.get("Personnel");
// unlock owner
Address owner = Address.wrap("a06f02e986965ddd3398c4de87e3708072ad58d96e9c53e87c31c8c970b211e5");
boolean isUnlocked = api.getWallet().unlockAccount(owner, "password", 100).getObject();
System.out.format("owner account %s%n", isUnlocked ? "unlocked" : "locked");
// deploy contract
ContractDeploy.ContractDeployBuilder builder = new ContractDeploy.ContractDeployBuilder()
.compileResponse(contract).value(BigInteger.ZERO).nrgPrice(NRG_PRICE_MIN)
.nrgLimit(NRG_LIMIT_CONTRACT_CREATE_MAX).from(owner).data(ByteArrayWrapper.wrap(Bytesable.NULL_BYTE));
DeployResponse contractResponse = api.getTx().contractDeploy(builder.createContractDeploy()).getObject();
// print response
Hash256 txHash = contractResponse.getTxid();
Address contractAccount = contractResponse.getAddress();
System.out.format("%ntransaction hash:%n\t%s%ncontract address: %n\t%s%n", txHash, contractAccount);
// get & print receipt
TxReceipt txReceipt = api.getTx().getTxReceipt(txHash).getObject();
System.out.format("%ntransaction receipt:%n%s%n", txReceipt);
// contract source code
String source_personnel =
"contract Personnel { address public owner; modifier onlyOwner() { require(msg.sender == owner); _;} "
+ "mapping(bytes32 => address) private userList; /** 3 LSB bits for each privilege type */ "
+ "mapping(address => bytes1) private userPrivilege; function Personnel(){ owner = msg.sender; } "
+ "event UserAdded(string _stamp); event AddressAdded(address indexed _addr); "
+ "function getUserAddress(string _stamp) constant returns (address){ return userList[sha3(_stamp)]; } "
+ "function addUser(string _stamp, address _addr, bytes1 _userPrivilege) "
+ "onlyOwner{ userList[sha3(_stamp)] = _addr; userPrivilege[_addr] = _userPrivilege; "
+ "UserAdded(_stamp); } function addAddress(string _stamp, address _addr) "
+ "onlyOwner{ userList[sha3(_stamp)] = _addr; AddressAdded(_addr); } }";
// unlock owner
Address owner = Address.wrap("a06f02e986965ddd3398c4de87e3708072ad58d96e9c53e87c31c8c970b211e5");
boolean isUnlocked = api.getWallet().unlockAccount(owner, "password", 100).getObject();
System.out.format("owner account %s%n", isUnlocked ? "unlocked" : "locked");
// clear old deploy
api.getContractController().clear();
// deploy contract
ApiMsg msg = api.getContractController()
.createFromSource(source_personnel, owner, NRG_LIMIT_CONTRACT_CREATE_MAX, NRG_PRICE_MIN);
if (msg.isError()) {
System.out.println("deploy contract failed! " + msg.getErrString());
} else {
// get contract
IContract contractResponse = api.getContractController().getContract();
// print response
Hash256 txHash = contractResponse.getDeployTxId();
Address contractAccount = contractResponse.getContractAddress();
System.out.format("%ntransaction hash:%n\t%s%ncontract address: %n\t%s%n", txHash, contractAccount);
// get & print receipt
TxReceipt txReceipt = api.getTx().getTxReceipt(txHash).getObject();
System.out.format("%ntransaction receipt:%n%s%n", txReceipt);
}
// contract source code
const source_personnel = "contract Personnel { address public owner; modifier onlyOwner() { require(msg.sender == owner); _;} "
+ "mapping(bytes32 => address) private userList; /** 3 LSB bits for each privilege type */ "
+ "mapping(address => bytes1) private userPrivilege; function Personnel(){ owner = msg.sender; } "
+ "event UserAdded(string _stamp); event AddressAdded(address indexed _addr); "
+ "function getUserAddress(string _stamp) constant returns (address){ return userList[sha3(_stamp)]; } "
+ "function addUser(string _stamp, address _addr, bytes1 _userPrivilege) "
+ "onlyOwner{ userList[sha3(_stamp)] = _addr; userPrivilege[_addr] = _userPrivilege; "
+ "UserAdded(_stamp); } function addAddress(string _stamp, address _addr) "
+ "onlyOwner{ userList[sha3(_stamp)] = _addr; AddressAdded(_addr); } }";
// compile code
let result = web3.eth.compile.solidity(source_personnel);
let abi = result.Personnel.info.abiDefinition;
let code = result.Personnel.code;
// unlock owner
let owner = 'a06f02e986965ddd3398c4de87e3708072ad58d96e9c53e87c31c8c970b211e5';
let isUnlocked = web3.personal.unlockAccount(owner, "password", 100);
console.log("owner account " + (isUnlocked ? "unlocked" : "locked"));
// deploy contract
let response = web3.eth.contract(abi).new({from: owner, data: code, gasPrice: 10000000000, gas: 5000000});
// print response
let txHash = response.transactionHash;
let contractAccount = response.address;
// note that the address is not defined in the response
console.log("\ntransaction hash:\n\t" + txHash + "\ncontract address:\n\t" + contractAccount);
// get & print receipt
txReceipt = web3.eth.getTransactionReceipt(txHash);
// repeat till tx processed
while (txReceipt == null) {
// wait 10 sec
sleep(10000);
txReceipt = web3.eth.getTransactionReceipt(txHash);
}
// getting the address from the receipt
contractAccount = txReceipt.contractAddress;
console.log("\ncontract address:\n\t" + contractAccount);
// print full receipt
console.log("\ntransaction receipt:");
console.log(txReceipt);
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
Sample output:
owner account unlocked
transaction hash:
226b57f1b342892718e3776c6d9e53256e26b53714e291c4aff892b5ab9c259b
contract address:
a0c751cd789de21265f16d1c2cf6e9c5bf56fd1cbeb30704fd2b017e4ef65e8f
transaction receipt:
txIndex: 0,
blockNumber: 307647,
nrg: 349674,
nrgCumulativeUsed: 349674,
blockHash: 0x8882810ca8481b5532055c00beb44a121e0ca47c77fca099f4aa204649024282,
txHash: 0x226b57f1b342892718e3776c6d9e53256e26b53714e291c4aff892b5ab9c259b,
from: 0xa06f02e986965ddd3398c4de87e3708072ad58d96e9c53e87c31c8c970b211e5,
to: 0x,
contractAddress: a0c751cd789de21265f16d1c2cf6e9c5bf56fd1cbeb30704fd2b017e4ef65e8f,
log:
owner account unlocked
transaction hash:
0x1957290572a6785f550adcaaeedccc6c71c78ba60f7e236b23ae8ae0ccb798a1
contract address:
undefined
contract address:
0xa0effc1986a633667d32cccc3402457a6badfed493dcb545c11ef5fd3decdc0e
transaction receipt:
{ blockHash: '0x574b8ffef09084283aa3febfca060ba33724f5d8cd028877941e56dff782c318',
nrgPrice: '0x02540be400',
logsBloom: '00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
nrgUsed: 349674,
contractAddress: '0xa0effc1986a633667d32cccc3402457a6badfed493dcb545c11ef5fd3decdc0e',
transactionIndex: 0,
transactionHash: '0x1957290572a6785f550adcaaeedccc6c71c78ba60f7e236b23ae8ae0ccb798a1',
gasLimit: '0x4c4b40',
cumulativeNrgUsed: 349674,
gasUsed: '0x0555ea',
blockNumber: 313456,
root: '0bb58744440f2cd6951081956dfbe0e447dec5e34b80324ff1ccce0950242b94',
cumulativeGasUsed: '0x555ea',
from: '0xa06f02e986965ddd3398c4de87e3708072ad58d96e9c53e87c31c8c970b211e5',
to: '0x',
logs: [],
gasPrice: '0x02540be400',
status: '0x1' }
Execute Contract Function
The examples below show how to use the APIs to execute a contract function. In each code snippet, a function to add information to the contract is executed after which we use a get function to verify the value was added. The transaction hashes for both calls are printed to the standard output. Note that the get call does not create a transaction.
// input values
Hash256 txHash = Hash256.wrap("0xb35c28a10bc996f1cdd81425e6c90d4c841ed6ba6c7f039e76d448a6c869d7bc");
String source_personnel =
"contract Personnel { address public owner; modifier onlyOwner() { require(msg.sender == owner); _;} "
+ "mapping(bytes32 => address) private userList; /** 3 LSB bits for each privilege type */ "
+ "mapping(address => bytes1) private userPrivilege; function Personnel(){ owner = msg.sender; } "
+ "event UserAdded(string _stamp); event AddressAdded(address indexed _addr); "
+ "function getUserAddress(string _stamp) constant returns (address){ return userList[sha3(_stamp)]; } "
+ "function addUser(string _stamp, address _addr, bytes1 _userPrivilege) "
+ "onlyOwner{ userList[sha3(_stamp)] = _addr; userPrivilege[_addr] = _userPrivilege; "
+ "UserAdded(_stamp); } function addAddress(string _stamp, address _addr) "
+ "onlyOwner{ userList[sha3(_stamp)] = _addr; AddressAdded(_addr); } }";
String addressToAdd = "a0ab123ab123ab123ab123ab123ab123ab123ab123ab123ab123ab123ab123ab";
String keyToAdd = "key-ab123";
// get contract object parameters
TxReceipt txReceipt = api.getTx().getTxReceipt(txHash).getObject();
Address contractAccount = txReceipt.getContractAddress();
Address ownerAddress = txReceipt.getFrom();
String abiDefinition = ((Map<String, CompileResponse>) api.getTx().compile(source_personnel).getObject())
.get("Personnel").getAbiDefString();
// get contract object using ownerAddress & contractAccount & abiDefinition
IContract ctr = api.getContractController().getContractAt(ownerAddress, contractAccount, abiDefinition);
// unlock account
api.getWallet().unlockAccount(ownerAddress, "password");
// execute function: adding a user address
ContractResponse rsp = ctr.newFunction("addAddress").setFrom(ownerAddress).setParam(ISString.copyFrom(keyToAdd))
.setParam(IAddress.copyFrom(addressToAdd)).setTxNrgLimit(NRG_LIMIT_TX_MAX).setTxNrgPrice(NRG_PRICE_MIN)
.build().execute().getObject();
System.out.println("ADD response:\n" + rsp);
// wait for tx to be processed
Thread.sleep(30000L);
// get & print receipt
txReceipt = api.getTx().getTxReceipt(rsp.getTxHash()).getObject();
System.out.format("ADD transaction receipt:%n%s%n", txReceipt);
// call function: getting a user address
rsp = ctr.newFunction("getUserAddress").setParam(ISString.copyFrom(keyToAdd)).build().execute().getObject();
System.out.println("GET response:\n" + rsp);
// checking that received value matches input
String received = Address.wrap((byte[]) rsp.getData().get(0)).toString();
if (!received.equals(addressToAdd)) {
System.out.format("%nThe received value:%n%s%ndoes not match the given parameter:%n%s%n",
received,
addressToAdd);
} else {
System.out.format("%nThe received value:%n%s%nmatches the given parameter:%n%s%n", received, addressToAdd);
}
// input values
let txHash = '0xb35c28a10bc996f1cdd81425e6c90d4c841ed6ba6c7f039e76d448a6c869d7bc';
const source_personnel = "contract Personnel { address public owner; modifier onlyOwner() { require(msg.sender == owner); _;} "
+ "mapping(bytes32 => address) private userList; /** 3 LSB bits for each privilege type */ "
+ "mapping(address => bytes1) private userPrivilege; function Personnel(){ owner = msg.sender; } "
+ "event UserAdded(string _stamp); event AddressAdded(address indexed _addr); "
+ "function getUserAddress(string _stamp) constant returns (address){ return userList[sha3(_stamp)]; } "
+ "function addUser(string _stamp, address _addr, bytes1 _userPrivilege) "
+ "onlyOwner{ userList[sha3(_stamp)] = _addr; userPrivilege[_addr] = _userPrivilege; "
+ "UserAdded(_stamp); } function addAddress(string _stamp, address _addr) "
+ "onlyOwner{ userList[sha3(_stamp)] = _addr; AddressAdded(_addr); } }";
let addressToAdd = "0xa0ab456ab456ab456ab456ab456ab456ab456ab456ab456ab456ab456ab456ab";
let keyToAdd = "key-ab456";
// get contract object parameters
let txReceipt = web3.eth.getTransactionReceipt(txHash);
let contractAccount = txReceipt.contractAddress;
let ownerAddress = txReceipt.from;
let abiDefinition = web3.eth.compile.solidity(source_personnel).Personnel.info.abiDefinition;
// get contract object using ownerAddress & contractAccount & abiDefinition
let ctr = web3.eth.contract(abiDefinition).at(contractAccount);
// unlock account
web3.personal.unlockAccount(ownerAddress, "password", 100);
// execute function: adding a user address
let rsp = ctr.addAddress(keyToAdd, addressToAdd, {from: ownerAddress, gas: 2000000, gasPrice: 10000000000});
console.log("ADD response: " + rsp);
// get & print receipt
txReceipt = web3.eth.getTransactionReceipt(rsp);
// repeat till tx processed
while (txReceipt == null) {
// wait 10 sec
sleep(10000);
txReceipt = web3.eth.getTransactionReceipt(rsp);
}
console.log("\nADD transaction receipt:")
console.log(txReceipt);
// call function: getting a user address
rsp = ctr.getUserAddress(keyToAdd);
console.log("\nGET response: " + rsp);
// checking that received value matches input
if (!rsp == addressToAdd) {
console.log("\nThe received value:\n%s\n does not match the given parameter:\n%s\n", rsp, addressToAdd);
} else {
console.log("\nThe received value:\n%s\nmatches the given parameter:\n%s\n", rsp, addressToAdd);
}
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
Sample output:
ADD response:
constant: false,
data:
transactionHash: 8e2f8e2b18033aed17bead6dddca8ec2a8290bdb3e317ec82cc5ed89eea6c4b4,
status: Transaction Done.,
error: null
ADD transaction receipt:
txIndex: 0,
blockNumber: 314761,
nrg: 44010,
nrgCumulativeUsed: 44010,
blockHash: 0xe6a5d4fbde342bc11f3e6b9c9bd97ab8a0db12b60a2581dbc330fcc9510ba6cc,
txHash: 0x8e2f8e2b18033aed17bead6dddca8ec2a8290bdb3e317ec82cc5ed89eea6c4b4,
from: 0xa06f02e986965ddd3398c4de87e3708072ad58d96e9c53e87c31c8c970b211e5,
to: 0xa0f2bc28cc71bf81e38e91bcfdd1a89e8b67af39b65d3a046b1627482a0a72e5,
contractAddress: ,
log:
[
address: 0xa0f2bc28cc71bf81e38e91bcfdd1a89e8b67af39b65d3a046b1627482a0a72e5,
data: 0x,
topics:
[
0x0xa226db3f664042183ee0281230bba26cbf7b5057e50aee7f25a175ff45ce4d7f,
0x0xa0ab123ab123ab123ab123ab123ab123ab123ab123ab123ab123ab123ab123ab
]
]
GET response:
constant: true,
data:
[a0ab123ab123ab123ab123ab123ab123ab123ab123ab123ab123ab123ab123ab]
transactionHash: 0000000000000000000000000000000000000000000000000000000000000000,
status: Api failed.,
error: null
The received value:
a0ab123ab123ab123ab123ab123ab123ab123ab123ab123ab123ab123ab123ab
matches the given parameter:
a0ab123ab123ab123ab123ab123ab123ab123ab123ab123ab123ab123ab123ab
ADD response: 0xb1bdd53910ae2fb4155f48bfc0b65f02faf3221f90a929168526e334f828f771
ADD transaction receipt:
{ blockHash: '0x544f3af1d55207705a1c38cb89cc0a5295a2d874993159f3edf3389397a8f094',
nrgPrice: '0x02540be400',
logsBloom: '00000000000000004000000400000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000020000000000400000000000000000000000000000000000000000000002000000000000000000000200000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
nrgUsed: 68010,
contractAddress: null,
transactionIndex: 0,
transactionHash: '0xb1bdd53910ae2fb4155f48bfc0b65f02faf3221f90a929168526e334f828f771',
gasLimit: '0x1e8480',
cumulativeNrgUsed: 68010,
gasUsed: '0x0109aa',
blockNumber: 314695,
root: '97bf8fa45395ce9da3304152b6d7379036bbfafa0a26241916ac6f821f075a73',
cumulativeGasUsed: '0x109aa',
from: '0xa06f02e986965ddd3398c4de87e3708072ad58d96e9c53e87c31c8c970b211e5',
to: '0xa0f2bc28cc71bf81e38e91bcfdd1a89e8b67af39b65d3a046b1627482a0a72e5',
logs:
[ { address: '0xa0f2bc28cc71bf81e38e91bcfdd1a89e8b67af39b65d3a046b1627482a0a72e5',
logIndex: 0,
data: '0x',
topics: [Array],
blockNumber: 314695,
transactionIndex: 0 } ],
gasPrice: '0x02540be400',
status: '0x1' }
GET response: 0xa0ab456ab456ab456ab456ab456ab456ab456ab456ab456ab456ab456ab456ab
The received value:
0xa0ab456ab456ab456ab456ab456ab456ab456ab456ab456ab456ab456ab456ab
matches the given parameter:
0xa0ab456ab456ab456ab456ab456ab456ab456ab456ab456ab456ab456ab456ab
Call Contract Function
The examples below show how to use the APIs to call a contract function.
The functionality is compatible with eth_call
.
Java: The example in Execute Contract Function also applies where ctr.newFunction("getUserAddress").setParam(ISString.copyFrom(keyToAdd)).build().execute()
defaults to a call (does not create a transaction).
JavaScript: The same example as in Execute Contract Function applies where ctr.getUserAddress(keyToAdd)
defaults to a call (does not create a transaction).
// input values
Hash256 txHash = Hash256.wrap("0xb35c28a10bc996f1cdd81425e6c90d4c841ed6ba6c7f039e76d448a6c869d7bc");
String source_personnel =
"contract Personnel { address public owner; modifier onlyOwner() { require(msg.sender == owner); _;} "
+ "mapping(bytes32 => address) private userList; /** 3 LSB bits for each privilege type */ "
+ "mapping(address => bytes1) private userPrivilege; function Personnel(){ owner = msg.sender; } "
+ "event UserAdded(string _stamp); event AddressAdded(address indexed _addr); "
+ "function getUserAddress(string _stamp) constant returns (address){ return userList[sha3(_stamp)]; } "
+ "function addUser(string _stamp, address _addr, bytes1 _userPrivilege) "
+ "onlyOwner{ userList[sha3(_stamp)] = _addr; userPrivilege[_addr] = _userPrivilege; "
+ "UserAdded(_stamp); } function addAddress(string _stamp, address _addr) "
+ "onlyOwner{ userList[sha3(_stamp)] = _addr; AddressAdded(_addr); } }";
String addressToAdd = "a0ab234ab234ab234ab234ab234ab234ab234ab234ab234ab234ab234ab234ab";
String keyToAdd = "key-ab123";
// get contract object parameters
TxReceipt txReceipt = api.getTx().getTxReceipt(txHash).getObject();
Address contractAccount = txReceipt.getContractAddress();
Address ownerAddress = txReceipt.getFrom();
String abiDefinition = ((Map<String, CompileResponse>) api.getTx().compile(source_personnel).getObject())
.get("Personnel").getAbiDefString();
// get contract object using ownerAddress & contractAccount & abiDefinition
IContract ctr = api.getContractController().getContractAt(ownerAddress, contractAccount, abiDefinition);
// unlock account
api.getWallet().unlockAccount(ownerAddress, "password");
// call function: adding a user address
ContractResponse rsp = ctr.newFunction("addAddress").setFrom(ownerAddress).setParam(ISString.copyFrom(keyToAdd))
.setParam(IAddress.copyFrom(addressToAdd)).setTxNrgLimit(NRG_LIMIT_TX_MAX).setTxNrgPrice(NRG_PRICE_MIN)
.build().call().getObject();
System.out.println("ADD response:\n" + rsp);
// call function: getting a user address
rsp = ctr.newFunction("getUserAddress").setParam(ISString.copyFrom(keyToAdd)).build().call().getObject();
System.out.println("GET response:\n" + rsp);
// checking that received value matches input
String received = Address.wrap((byte[]) rsp.getData().get(0)).toString();
if (!received.equals(addressToAdd)) {
System.out.format("The received value:%n%s%ndoes not match the given parameter:%n%s%n",
received,
addressToAdd);
} else {
System.out.format("The received value:%n%s%nmatches the given parameter:%n%s%n", received, addressToAdd);
}
Sample output:
ADD response:
constant: true,
data:
transactionHash: 0000000000000000000000000000000000000000000000000000000000000000,
status: Api failed.,
error: null
GET response:
constant: true,
data:
[a0ab123ab123ab123ab123ab123ab123ab123ab123ab123ab123ab123ab123ab]
transactionHash: 0000000000000000000000000000000000000000000000000000000000000000,
status: Api failed.,
error: null
The received value:
a0ab123ab123ab123ab123ab123ab123ab123ab123ab123ab123ab123ab123ab
does not match the given parameter:
a0ab234ab234ab234ab234ab234ab234ab234ab234ab234ab234ab234ab234ab
Complete Examples
Each code example below illustrates APIs interactions for the following use cases:
- get available compilers,
- compile solidity code,
- get current NRG price,
- estimate needed NRG,
- get contract code,
- get stored value,
- deploy a contract,
- execute a contract function, and
- call a contract function.
package org.aion.tutorials;
import org.aion.api.IAionAPI;
import org.aion.api.IContract;
import org.aion.api.IUtils;
import org.aion.api.sol.IAddress;
import org.aion.api.sol.ISString;
import org.aion.api.type.*;
import org.aion.base.type.Address;
import org.aion.base.type.Hash256;
import org.aion.base.util.ByteArrayWrapper;
import org.aion.base.util.Bytesable;
import java.math.BigInteger;
import java.util.Map;
import static org.aion.api.ITx.*;
public class ContractExample {
public static void main(String[] args) throws InterruptedException {
// connect to Java API
IAionAPI api = IAionAPI.init();
ApiMsg apiMsg = api.connect(IAionAPI.LOCALHOST_URL);
// failed connection
if (apiMsg.isError()) {
System.out.format("Could not connect due to <%s>%n", apiMsg.getErrString());
System.exit(-1);
}
// 1. eth_getCompilers
// not available/needed at present
// 2. eth_compileSolidity
// contract source code
String source_ticker = "contract ticker { uint public val; function tick () { val+= 1; } }";
// compile code
Map<String, CompileResponse> result = api.getTx().compile(source_ticker).getObject();
// print result
System.out.println(result);
// 3. eth_gasPrice
// get NRG price
long price = api.getTx().getNrgPrice().getObject();
// print price
System.out.println("\ncurrent NRG price = " + price + " nAmp");
// 4. eth_estimateGas
// get NRG estimate for contract
long estimate = api.getTx().estimateNrg(result.get("ticker").getCode()).getObject();
// print estimate
System.out.println("\nNRG estimate for contract = " + estimate + " NRG");
// transaction data
Address sender = Address.wrap("a06f02e986965ddd3398c4de87e3708072ad58d96e9c53e87c31c8c970b211e5");
Address receiver = Address.wrap("a0bd0ef93902d9e123521a67bef7391e9487e963b2346ef3b3ff78208835545e");
BigInteger amount = BigInteger.valueOf(1_000_000_000_000_000_000L); // = 1 AION
ByteArrayWrapper data = ByteArrayWrapper.wrap("test.message".getBytes());
// prepare transaction
TxArgs tx = new TxArgs.TxArgsBuilder().data(data).from(sender).to(receiver).value(amount).createTxArgs();
// get NRG estimate for transaction
estimate = api.getTx().estimateNrg(tx).getObject();
// print estimate
System.out.println("\nNRG estimate for transaction = " + estimate + " NRG");
// 5. eth_getCode
// set contract account
Address contractAccount = Address.wrap("a0960fcb7d6423a0446243916c7c6360543b3d2f9c5e1c5ff7badb472b782b79");
// get code from latest block
long blockNumber = -1L; // indicates latest block
byte[] code = api.getTx().getCode(contractAccount, blockNumber).getObject();
// print code
System.out.println("\n0x" + IUtils.bytes2Hex(code));
// 6. eth_getStorageAt
// view contract creation tx
Hash256 txHash = Hash256.wrap("0xb42a5f995450531f66e7db40efdfad2c310fa0f8dbca2a88c31fdc4837368e48");
TxReceipt receipt = api.getTx().getTxReceipt(txHash).getObject();
System.out.println("\n" + receipt);
// set contract account
contractAccount = receipt.getContractAddress();
// get value from storage
String valuePos0 = api.getChain().getStorageAt(contractAccount, 0, blockNumber).getObject();
String valuePos1 = api.getChain().getStorageAt(contractAccount, 1, blockNumber).getObject();
// print values
// in this case the first two values are the contract owner
System.out.println("concatenated values = " + valuePos0 + valuePos1);
// 7.a) deploy contract
// contract source code
String source_personnel =
"contract Personnel { address public owner; modifier onlyOwner() { require(msg.sender == owner); _;} "
+ "mapping(bytes32 => address) private userList; /** 3 LSB bits for each privilege type */ "
+ "mapping(address => bytes1) private userPrivilege; function Personnel(){ owner = msg.sender; } "
+ "event UserAdded(string _stamp); event AddressAdded(address indexed _addr); "
+ "function getUserAddress(string _stamp) constant returns (address){ return userList[sha3(_stamp)]; } "
+ "function addUser(string _stamp, address _addr, bytes1 _userPrivilege) "
+ "onlyOwner{ userList[sha3(_stamp)] = _addr; userPrivilege[_addr] = _userPrivilege; "
+ "UserAdded(_stamp); } function addAddress(string _stamp, address _addr) "
+ "onlyOwner{ userList[sha3(_stamp)] = _addr; AddressAdded(_addr); } }";
// compile code
result = api.getTx().compile(source_personnel).getObject();
CompileResponse contract = result.get("Personnel");
// unlock owner
Address owner = Address.wrap("a06f02e986965ddd3398c4de87e3708072ad58d96e9c53e87c31c8c970b211e5");
boolean isUnlocked = api.getWallet().unlockAccount(owner, "password", 100).getObject();
System.out.format("\nowner account %s%n", isUnlocked ? "unlocked" : "locked");
// deploy contract
ContractDeploy.ContractDeployBuilder builder = new ContractDeploy.ContractDeployBuilder()
.compileResponse(contract).value(BigInteger.ZERO).nrgPrice(NRG_PRICE_MIN)
.nrgLimit(NRG_LIMIT_CONTRACT_CREATE_MAX).from(owner).data(ByteArrayWrapper.wrap(Bytesable.NULL_BYTE));
DeployResponse contractResponse = api.getTx().contractDeploy(builder.createContractDeploy()).getObject();
// print response
txHash = contractResponse.getTxid();
contractAccount = contractResponse.getAddress();
System.out.format("%ntransaction hash:%n\t%s%ncontract address: %n\t%s%n", txHash, contractAccount);
// get & print receipt
TxReceipt txReceipt = api.getTx().getTxReceipt(txHash).getObject();
System.out.format("%ntransaction receipt:%n%s%n", txReceipt);
// 7.b) deploy contract
isUnlocked = api.getWallet().unlockAccount(owner, "password", 100).getObject();
System.out.format("%nowner account %s%n", isUnlocked ? "unlocked" : "locked");
// clear old deploy
api.getContractController().clear();
// deploy contract
ApiMsg msg = api.getContractController()
.createFromSource(source_personnel, owner, NRG_LIMIT_CONTRACT_CREATE_MAX, NRG_PRICE_MIN);
if (msg.isError()) {
System.out.println("deploy contract failed! " + msg.getErrString());
} else {
// get contract
IContract contractRsp = api.getContractController().getContract();
// print response
txHash = contractRsp.getDeployTxId();
contractAccount = contractRsp.getContractAddress();
System.out.format("%ntransaction hash:%n\t%s%ncontract address: %n\t%s%n", txHash, contractAccount);
// get & print receipt
txReceipt = api.getTx().getTxReceipt(txHash).getObject();
System.out.format("%ntransaction receipt:%n%s%n", txReceipt);
}
// 8. execute a contract function
// input values
txHash = Hash256.wrap("0xb35c28a10bc996f1cdd81425e6c90d4c841ed6ba6c7f039e76d448a6c869d7bc");
String addressToAdd = "a0ab123ab123ab123ab123ab123ab123ab123ab123ab123ab123ab123ab123ab";
String keyToAdd = "key-ab123";
// get contract object parameters
txReceipt = api.getTx().getTxReceipt(txHash).getObject();
contractAccount = txReceipt.getContractAddress();
Address ownerAddress = txReceipt.getFrom();
String abiDefinition = ((Map<String, CompileResponse>) api.getTx().compile(source_personnel).getObject())
.get("Personnel").getAbiDefString();
// get contract object using ownerAddress & contractAccount & abiDefinition
IContract ctr = api.getContractController().getContractAt(ownerAddress, contractAccount, abiDefinition);
// unlock account
api.getWallet().unlockAccount(ownerAddress, "password");
// execute function: adding a user address
ContractResponse rsp = ctr.newFunction("addAddress").setFrom(ownerAddress).setParam(ISString.copyFrom(keyToAdd))
.setParam(IAddress.copyFrom(addressToAdd)).setTxNrgLimit(NRG_LIMIT_TX_MAX).setTxNrgPrice(NRG_PRICE_MIN)
.build().execute().getObject();
System.out.println("ADD response:\n" + rsp);
// wait for tx to be processed
Thread.sleep(30000L);
// get & print receipt
txReceipt = api.getTx().getTxReceipt(rsp.getTxHash()).getObject();
System.out.format("ADD transaction receipt:%n%s%n", txReceipt);
// 9. eth_call
// call function: getting a user address
rsp = ctr.newFunction("getUserAddress").setParam(ISString.copyFrom(keyToAdd)).build().call().getObject();
System.out.println("GET response:\n" + rsp);
// checking that received value matches input
String received = Address.wrap((byte[]) rsp.getData().get(0)).toString();
if (!received.equals(addressToAdd)) {
System.out.format("The received value:%n%s%ndoes not match the given parameter:%n%s%n",
received,
addressToAdd);
} else {
System.out.format("The received value:%n%s%nmatches the given parameter:%n%s%n", received, addressToAdd);
}
// disconnect from api
api.destroyApi();
System.exit(0);
}
}
const Web3 = require('/path/to/aion/web3');
const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
// 1. eth_getCompilers
// get list of available compilers
let compilers = web3.eth.getCompilers();
// print
console.log("available compilers: " + compilers + "\n");
// 2. eth_compileSolidity
// contract source code
const source_ticker = 'contract ticker { uint public val; function tick () { val+= 1; } }';
// compile code
let result = web3.eth.compile.solidity(source_ticker);
// print result
console.log(result);
// 3. eth_gasPrice
// get NRG price
let price = web3.eth.gasPrice
// print price
console.log("\ncurrent NRG price = " + price + " nAmp");
// 4. eth_estimateGas
// compile contract source code
result = web3.eth.compile.solidity(source_ticker);
// get NRG estimate for contract
let estimate = web3.eth.estimateGas({data:result.ticker.code});
// print estimate
console.log("\nNRG estimate for contract = " + estimate + " NRG");
// transaction data
let sender = 'a06f02e986965ddd3398c4de87e3708072ad58d96e9c53e87c31c8c970b211e5';
let receiver = 'a0bd0ef93902d9e123521a67bef7391e9487e963b2346ef3b3ff78208835545e';
let amount = 1000000000000000000; // = 1 AION
let data = '0x746573742e6d657373616765'; // hex for "test.message"
// get NRG estimate for transaction
estimate = web3.eth.estimateGas({data: data, from: sender, to: receiver, value: amount})
// print estimate
console.log("\nNRG estimate for transaction = " + estimate + " NRG");
// 5. eth_getCode
// set contract account
let ctAcc = 'a0960fcb7d6423a0446243916c7c6360543b3d2f9c5e1c5ff7badb472b782b79';
// get code from latest block
let code = web3.eth.getCode(ctAcc, 'latest');
// print code
console.log("\n" + code + "\n");
// 6. eth_getStorageAt
// view contract creation tx
let txHash = '0xb42a5f995450531f66e7db40efdfad2c310fa0f8dbca2a88c31fdc4837368e48';
let receipt = web3.eth.getTransactionReceipt(txHash);
console.log(receipt);
// set contract account
let contractAccount = receipt.contractAddress;
// get value from storage
let valuePos0 = web3.eth.getStorageAt(contractAccount, 0, 'latest');
let valuePos1 = web3.eth.getStorageAt(contractAccount, 1, 'latest');
// print values
// in this case the first two values are the contract owner
console.log("\nconcatenated values = " + valuePos0 + valuePos1);
// 7. deploy contract
// contract source code
const source_personnel = "contract Personnel { address public owner; modifier onlyOwner() { require(msg.sender == owner); _;} "
+ "mapping(bytes32 => address) private userList; /** 3 LSB bits for each privilege type */ "
+ "mapping(address => bytes1) private userPrivilege; function Personnel(){ owner = msg.sender; } "
+ "event UserAdded(string _stamp); event AddressAdded(address indexed _addr); "
+ "function getUserAddress(string _stamp) constant returns (address){ return userList[sha3(_stamp)]; } "
+ "function addUser(string _stamp, address _addr, bytes1 _userPrivilege) "
+ "onlyOwner{ userList[sha3(_stamp)] = _addr; userPrivilege[_addr] = _userPrivilege; "
+ "UserAdded(_stamp); } function addAddress(string _stamp, address _addr) "
+ "onlyOwner{ userList[sha3(_stamp)] = _addr; AddressAdded(_addr); } }";
// compile code
result = web3.eth.compile.solidity(source_personnel);
let abi = result.Personnel.info.abiDefinition;
code = result.Personnel.code;
// unlock owner
let owner = 'a06f02e986965ddd3398c4de87e3708072ad58d96e9c53e87c31c8c970b211e5';
let isUnlocked = web3.personal.unlockAccount(owner, "password", 100);
console.log("\nowner account " + (isUnlocked ? "unlocked" : "locked"));
// deploy contract
let response = web3.eth.contract(abi).new({from: owner, data: code, gasPrice: 10000000000, gas: 5000000});
// print response
txHash = response.transactionHash;
contractAccount = response.address;
// note that the address is not defined in the response
console.log("\ntransaction hash:\n\t" + txHash + "\ncontract address:\n\t" + contractAccount);
// get & print receipt
txReceipt = web3.eth.getTransactionReceipt(txHash);
// repeat till tx processed
while (txReceipt == null) {
// wait 10 sec
sleep(10000);
txReceipt = web3.eth.getTransactionReceipt(txHash);
}
// getting the address from the receipt
contractAccount = txReceipt.contractAddress;
console.log("\ncontract address:\n\t" + contractAccount);
// print full receipt
console.log("\ntransaction receipt:");
console.log(txReceipt);
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
// 8. execute a contract function
// input values
txHash = '0xb35c28a10bc996f1cdd81425e6c90d4c841ed6ba6c7f039e76d448a6c869d7bc';
let addressToAdd = "0xa0ab456ab456ab456ab456ab456ab456ab456ab456ab456ab456ab456ab456ab";
let keyToAdd = "key-ab456";
// get contract object parameters
txReceipt = web3.eth.getTransactionReceipt(txHash);
contractAccount = txReceipt.contractAddress;
let ownerAddress = txReceipt.from;
let abiDefinition = web3.eth.compile.solidity(source_personnel).Personnel.info.abiDefinition;
// get contract object using ownerAddress & contractAccount & abiDefinition
let ctr = web3.eth.contract(abiDefinition).at(contractAccount);
// unlock account
web3.personal.unlockAccount(ownerAddress, "password", 100);
// execute function: adding a user address
let rsp = ctr.addAddress(keyToAdd, addressToAdd, {from: ownerAddress, gas: 2000000, gasPrice: 10000000000});
console.log("\nADD response: " + rsp);
// get & print receipt
txReceipt = web3.eth.getTransactionReceipt(rsp);
// repeat till tx processed
while (txReceipt == null) {
// wait 10 sec
sleep(10000);
txReceipt = web3.eth.getTransactionReceipt(rsp);
}
console.log("\nADD transaction receipt:")
console.log(txReceipt);
// 9. eth_call
// call function: getting a user address
rsp = ctr.getUserAddress(keyToAdd);
console.log("\nGET response: " + rsp);
// checking that received value matches input
if (!rsp == addressToAdd) {
console.log("\nThe received value:\n%s\n does not match the given parameter:\n%s\n", rsp, addressToAdd);
} else {
console.log("\nThe received value:\n%s\nmatches the given parameter:\n%s\n", rsp, addressToAdd);
}
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
Sample output:
{ticker=code :0x605060405234156100105760006000fd5b610015565b60c2806100236000396000f30060506040526000356c01000000000000000000000000900463ffffffff1680633c6bb43614603b5780633eaf5d9f146062576035565b60006000fd5b341560465760006000fd5b604c6075565b6040518082815260100191505060405180910390f35b3415606d5760006000fd5b6073607e565b005b60006000505481565b6001600060008282825054019250508190909055505b5600a165627a7a723058201c1817d957da90680b7c55720aff16e7a4407b31f7480f63210748a5cc4efb0c0029,
source :contract ticker { uint public val; function tick () { val+= 1; } },
language :,
languageVersion: ,
compilerVersion: ,
compilerOption: ,
abiDefString: [{"outputs":[{"name":"","type":"uint128"}],"constant":true,"payable":false,"inputs":[],"name":"val","type":"function"},{"outputs":[],"constant":false,"payable":false,"inputs":[],"name":"tick","type":"function"}],
abiDefinition:
[
constant: true,
anonymous: false,
payable: false,
type: function,
name: val,
inputs:
outputs:
[
indexed: false,
type: uint128,
name: ,
paramLengths:
[
]
]
isEvent: false,
isConstructor: false,
isFallback: false,
hashed: 3c6bb436
],
[
constant: false,
anonymous: false,
payable: false,
type: function,
name: tick,
inputs:
outputs:
isEvent: false,
isConstructor: false,
isFallback: false,
hashed: 3eaf5d9f
]
userDoc: constant: false,
name: ,
type: ,
inputs:
outputs:
,
developerDocconstant: false,
name: ,
type: ,
inputs:
outputs:
}
current NRG price = 10000000000 nAmp
NRG estimate for contract = 233661 NRG
NRG estimate for transaction = 21768 NRG
0x60506040526000356c01000000000000000000000000900463ffffffff1680630fd5f53f146100545780634985e85c146100e25780638da5cb5b1461015f578063ceb35b0f146101905761004e565b60006000fd5b34156100605760006000fd5b6100e06004808035906010019082018035906010019191908080600f01601080910402601001604051908101604052809392919081815260100183838082843782019150505050505090909190808060100135903590916020019091929080356effffffffffffffffffffffffffffff1916906010019091905050610203565b005b34156100ee5760006000fd5b6101426004808035906010019082018035906010019191908080600f0160108091040260100160405190810160405280939291908181526010018383808284378201915050505050509090919050506103af565b604051808383825281601001526020019250505060405180910390f35b341561016b5760006000fd5b610173610457565b604051808383825281601001526020019250505060405180910390f35b341561019c5760006000fd5b6102016004808035906010019082018035906010019191908080600f0160108091040260100160405190810160405280939291908181526010018383808284378201915050505050509090919080806010013590359091602001909192905050610466565b005b600060005080600101549054339091149190141615156102235760006000fd5b828260026000506000876040518082805190601001908083835b60108310151561026357805182525b60108201915060108101905060108303925061023d565b6001836010036101000a03801982511681845116808217855250505050505090500191505060405180910390209060001916909060001916908252816010015260200190815260100160002090506000508282909180600101839055555050508060036000506000858582528160100152602001908152601001600020905060006101000a81548160ff02191690836f01000000000000000000000000000000900402179055507fdb8f9fd4bfba5ae615ae02e8b4d281b887225fd3d34a5ac7b8d78df768bb63e7856040518080601001828103825283818151815260100191508051906010019080838360005b8381101561036d5780820151818401525b601081019050610351565b50505050905090810190600f16801561039a5780820380516001836010036101000a031916815260100191505b509250505060405180910390a15b5b50505050565b6000600060026000506000846040518082805190601001908083835b6010831015156103f157805182525b6010820191506010810190506010830392506103cb565b6001836010036101000a03801982511681845116808217855250505050505090500191505060405180910390209060001916909060001916908252816010015260200190815260100160002090506000508060010154905491509150610452565b915091565b60006000508060010154905482565b600060005080600101549054339091149190141615156104865760006000fd5b818160026000506000866040518082805190601001908083835b6010831015156104c657805182525b6010820191506010810190506010830392506104a0565b6001836010036101000a038019825116818451168082178552505050505050905001915050604051809103902090600019169090600019169082528160100152602001908152601001600020905060005082829091806001018390555550505081817fa226db3f664042183ee0281230bba26cbf7b5057e50aee7f25a175ff45ce4d7f60405160405180910390a25b5b5050505600a165627a7a723058201a36e96ba95136c7bf35a644bf8d3382c49dafc64e9362b025ed6f4eb99ed0640029
txIndex: 0,
blockNumber: 298287,
nrg: 349674,
nrgCumulativeUsed: 349674,
blockHash: 0x2e9b90a21f9702fde90807e42db0107ce85b8c14a99c1f9f76182ec20599eebc,
txHash: 0xb42a5f995450531f66e7db40efdfad2c310fa0f8dbca2a88c31fdc4837368e48,
from: 0xa0bd0ef93902d9e123521a67bef7391e9487e963b2346ef3b3ff78208835545e,
to: 0x,
contractAddress: a076ddb4cf37f7cd1360de9cf2336f75f06c38655da09d4e3f9b690acf57c2e1,
log:
concatenated values = a0bd0ef93902d9e123521a67bef7391e9487e963b2346ef3b3ff78208835545e
owner account unlocked
transaction hash:
bc3863dbc07a0020778a632622ebcd4ffea02f8790682a7bc70581c850aaf30f
contract address:
a0ae5633cd573960ca4d92b5127e49071214440bd070fc67bce495f214b7557e
transaction receipt:
txIndex: 0,
blockNumber: 314963,
nrg: 349674,
nrgCumulativeUsed: 349674,
blockHash: 0x331eae747c79f23d57bd28bf52257e8da35f65f4bfd5390e1831b66e4eea3c41,
txHash: 0xbc3863dbc07a0020778a632622ebcd4ffea02f8790682a7bc70581c850aaf30f,
from: 0xa06f02e986965ddd3398c4de87e3708072ad58d96e9c53e87c31c8c970b211e5,
to: 0x,
contractAddress: a0ae5633cd573960ca4d92b5127e49071214440bd070fc67bce495f214b7557e,
log:
owner account unlocked
transaction hash:
bf9627f42dcb942f8f06cd82a8b8764452d3fb1fe73d19ccf10526aa8ce5ecd0
contract address:
a0764b1ca325a15656e87216f6c4d80dc8d9e22fb99e4aa5e2529d1c8c8f4c25
transaction receipt:
txIndex: 0,
blockNumber: 314965,
nrg: 349674,
nrgCumulativeUsed: 349674,
blockHash: 0xbdc4b952822bf7091a55dad2f232f8ca11a6ba5146c404f5714f64447512931c,
txHash: 0xbf9627f42dcb942f8f06cd82a8b8764452d3fb1fe73d19ccf10526aa8ce5ecd0,
from: 0xa06f02e986965ddd3398c4de87e3708072ad58d96e9c53e87c31c8c970b211e5,
to: 0x,
contractAddress: a0764b1ca325a15656e87216f6c4d80dc8d9e22fb99e4aa5e2529d1c8c8f4c25,
log:
ADD response:
constant: false,
data:
transactionHash: db546561c8cef16a81fea509053a9917e65269bd7261191b8dd9272a9fa2fcc3,
status: Transaction Done.,
error: null
ADD transaction receipt:
txIndex: 0,
blockNumber: 314967,
nrg: 44010,
nrgCumulativeUsed: 44010,
blockHash: 0x52ef01f0938a8dd29b67ba18bd62ad3312f172e78580ad51034994878a5865e5,
txHash: 0xdb546561c8cef16a81fea509053a9917e65269bd7261191b8dd9272a9fa2fcc3,
from: 0xa06f02e986965ddd3398c4de87e3708072ad58d96e9c53e87c31c8c970b211e5,
to: 0xa0f2bc28cc71bf81e38e91bcfdd1a89e8b67af39b65d3a046b1627482a0a72e5,
contractAddress: ,
log:
[
address: 0xa0f2bc28cc71bf81e38e91bcfdd1a89e8b67af39b65d3a046b1627482a0a72e5,
data: 0x,
topics:
[
0x0xa226db3f664042183ee0281230bba26cbf7b5057e50aee7f25a175ff45ce4d7f,
0x0xa0ab123ab123ab123ab123ab123ab123ab123ab123ab123ab123ab123ab123ab
]
]
GET response:
constant: true,
data:
[a0ab123ab123ab123ab123ab123ab123ab123ab123ab123ab123ab123ab123ab]
transactionHash: 0000000000000000000000000000000000000000000000000000000000000000,
status: Api failed.,
error: null
The received value:
a0ab123ab123ab123ab123ab123ab123ab123ab123ab123ab123ab123ab123ab
matches the given parameter:
a0ab123ab123ab123ab123ab123ab123ab123ab123ab123ab123ab123ab123ab
available compilers: solidity
{ ticker:
{ code: '0x605060405234156100105760006000fd5b610015565b60c2806100236000396000f30060506040526000356c01000000000000000000000000900463ffffffff1680633c6bb43614603b5780633eaf5d9f146062576035565b60006000fd5b341560465760006000fd5b604c6075565b6040518082815260100191505060405180910390f35b3415606d5760006000fd5b6073607e565b005b60006000505481565b6001600060008282825054019250508190909055505b5600a165627a7a723058201c1817d957da90680b7c55720aff16e7a4407b31f7480f63210748a5cc4efb0c0029',
info:
{ abiDefinition: [Array],
languageVersion: '0',
language: 'Solidity',
compilerVersion: '0.4.15+commit.ecf81ee5.Linux.g++',
source: 'contract ticker { uint public val; function tick () { val+= 1; } }' } } }
current NRG price = 10000000000 nAmp
NRG estimate for contract = 233661 NRG
NRG estimate for transaction = 21768 NRG
0x60506040526000356c01000000000000000000000000900463ffffffff1680630fd5f53f146100545780634985e85c146100e25780638da5cb5b1461015f578063ceb35b0f146101905761004e565b60006000fd5b34156100605760006000fd5b6100e06004808035906010019082018035906010019191908080600f01601080910402601001604051908101604052809392919081815260100183838082843782019150505050505090909190808060100135903590916020019091929080356effffffffffffffffffffffffffffff1916906010019091905050610203565b005b34156100ee5760006000fd5b6101426004808035906010019082018035906010019191908080600f0160108091040260100160405190810160405280939291908181526010018383808284378201915050505050509090919050506103af565b604051808383825281601001526020019250505060405180910390f35b341561016b5760006000fd5b610173610457565b604051808383825281601001526020019250505060405180910390f35b341561019c5760006000fd5b6102016004808035906010019082018035906010019191908080600f0160108091040260100160405190810160405280939291908181526010018383808284378201915050505050509090919080806010013590359091602001909192905050610466565b005b600060005080600101549054339091149190141615156102235760006000fd5b828260026000506000876040518082805190601001908083835b60108310151561026357805182525b60108201915060108101905060108303925061023d565b6001836010036101000a03801982511681845116808217855250505050505090500191505060405180910390209060001916909060001916908252816010015260200190815260100160002090506000508282909180600101839055555050508060036000506000858582528160100152602001908152601001600020905060006101000a81548160ff02191690836f01000000000000000000000000000000900402179055507fdb8f9fd4bfba5ae615ae02e8b4d281b887225fd3d34a5ac7b8d78df768bb63e7856040518080601001828103825283818151815260100191508051906010019080838360005b8381101561036d5780820151818401525b601081019050610351565b50505050905090810190600f16801561039a5780820380516001836010036101000a031916815260100191505b509250505060405180910390a15b5b50505050565b6000600060026000506000846040518082805190601001908083835b6010831015156103f157805182525b6010820191506010810190506010830392506103cb565b6001836010036101000a03801982511681845116808217855250505050505090500191505060405180910390209060001916909060001916908252816010015260200190815260100160002090506000508060010154905491509150610452565b915091565b60006000508060010154905482565b600060005080600101549054339091149190141615156104865760006000fd5b818160026000506000866040518082805190601001908083835b6010831015156104c657805182525b6010820191506010810190506010830392506104a0565b6001836010036101000a038019825116818451168082178552505050505050905001915050604051809103902090600019169090600019169082528160100152602001908152601001600020905060005082829091806001018390555550505081817fa226db3f664042183ee0281230bba26cbf7b5057e50aee7f25a175ff45ce4d7f60405160405180910390a25b5b5050505600a165627a7a723058201a36e96ba95136c7bf35a644bf8d3382c49dafc64e9362b025ed6f4eb99ed0640029
{ blockHash: '0x2e9b90a21f9702fde90807e42db0107ce85b8c14a99c1f9f76182ec20599eebc',
nrgPrice: '0x02540be400',
logsBloom: '00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
nrgUsed: 349674,
contractAddress: '0xa076ddb4cf37f7cd1360de9cf2336f75f06c38655da09d4e3f9b690acf57c2e1',
transactionIndex: 0,
transactionHash: '0xb42a5f995450531f66e7db40efdfad2c310fa0f8dbca2a88c31fdc4837368e48',
gasLimit: '0x4c4b40',
cumulativeNrgUsed: 349674,
gasUsed: '0x0555ea',
blockNumber: 298287,
root: 'e433bbbc1714c2301faf7ac447c5881f345c32f8853e121694e430219cacb9d5',
cumulativeGasUsed: '0x555ea',
from: '0xa0bd0ef93902d9e123521a67bef7391e9487e963b2346ef3b3ff78208835545e',
to: '0x',
logs: [],
gasPrice: '0x02540be400',
status: '0x1' }
concatenated values = 0xa0bd0ef93902d9e123521a67bef7391e0x9487e963b2346ef3b3ff78208835545e
owner account unlocked
transaction hash:
0xc62efed241bca72bbf04bf018e86f55ddf76c37c90734e70eb4029821eb3d371
contract address:
undefined
contract address:
0xa0c12a380d25c48eb1ef57902ab9e9d88a260ea6d0c984269debd911e8ce6770
transaction receipt:
{ blockHash: '0xebc27704b64416ff78aa53141652612220ff603fbd0ead7b9ec52e692137f897',
nrgPrice: '0x02540be400',
logsBloom: '00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
nrgUsed: 349674,
contractAddress: '0xa0c12a380d25c48eb1ef57902ab9e9d88a260ea6d0c984269debd911e8ce6770',
transactionIndex: 0,
transactionHash: '0xc62efed241bca72bbf04bf018e86f55ddf76c37c90734e70eb4029821eb3d371',
gasLimit: '0x4c4b40',
cumulativeNrgUsed: 349674,
gasUsed: '0x0555ea',
blockNumber: 315024,
root: '262b17599aae7369a19c08880a4164eb329ae2ff93f3c047ec6a7693782307cb',
cumulativeGasUsed: '0x555ea',
from: '0xa06f02e986965ddd3398c4de87e3708072ad58d96e9c53e87c31c8c970b211e5',
to: '0x',
logs: [],
gasPrice: '0x02540be400',
status: '0x1' }
ADD response: 0xb4636988594e8c76f5a666c8fb9d9fd85eee62bc41b0c6376050150665dc07f2
ADD transaction receipt:
{ blockHash: '0x01c1363c109ef49b735603141fbb6c30f8ecb7bf4d9c51e27fd8ce8090cfb493',
nrgPrice: '0x02540be400',
logsBloom: '00000000000000004000000400000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000020000000000400000000000000000000000000000000000000000000002000000000000000000000200000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
nrgUsed: 44010,
contractAddress: null,
transactionIndex: 0,
transactionHash: '0xb4636988594e8c76f5a666c8fb9d9fd85eee62bc41b0c6376050150665dc07f2',
gasLimit: '0x1e8480',
cumulativeNrgUsed: 44010,
gasUsed: '0x00abea',
blockNumber: 315026,
root: 'c24aa18c7b77d72d2a554feada58228fe9938f6de3cc6124e3bf103eff0bbc10',
cumulativeGasUsed: '0xabea',
from: '0xa06f02e986965ddd3398c4de87e3708072ad58d96e9c53e87c31c8c970b211e5',
to: '0xa0f2bc28cc71bf81e38e91bcfdd1a89e8b67af39b65d3a046b1627482a0a72e5',
logs:
[ { address: '0xa0f2bc28cc71bf81e38e91bcfdd1a89e8b67af39b65d3a046b1627482a0a72e5',
logIndex: 0,
data: '0x',
topics: [Array],
blockNumber: 315026,
transactionIndex: 0 } ],
gasPrice: '0x02540be400',
status: '0x1' }
GET response: 0xa0ab456ab456ab456ab456ab456ab456ab456ab456ab456ab456ab456ab456ab
The received value:
0xa0ab456ab456ab456ab456ab456ab456ab456ab456ab456ab456ab456ab456ab
matches the given parameter:
0xa0ab456ab456ab456ab456ab456ab456ab456ab456ab456ab456ab456ab456ab
Updated over 6 years ago