Skip to main content

Getting started

Introduction#

This tutorial is mainly to guide users to create a simple HelloWorld smart contract using solidity language on Alaya, compile, deploy, and call this contract through alaya-truffle. If you want to use a richer API you can refer to Java SDK and JS SDK

alaya-truffle Introduction#

alaya-truffle is a tool provided by Alaya that can compile, deploy, and invoke smart contracts locally. For specific installation and usage manuals, refer to:

Create HelloWorld Contract#

pragma solidity ^0.5.17;
contract HelloWorld {        string name;        function setName(string memory _name) public returns(string memory){        name = _name;        return name;    }        function getName() public view returns(string memory){        return name;    }}

Contract Files Description:

  • pragma solidity ^0.5.17
    • pragma solidity: solidity version description 0.5.17:solidity version ^ :Indicates upward compatibility, that is, it can be compiled with a compiler above 0.5.17
  • contract HelloWorld
    • contract:contract keyword HelloWorld:contract name
  • string name
    • name:contract state variables string:the type of contract state variables
  • function setName(string memory _name) public returns(string memory)
    • function:function keyword setName:function name memory:declare the storage location of param name( function input parameters and output parameters must be declared as memory when the parameters type is string) _name:the local variables public:declare the visibility of the function name = _name:Assignment the local variable to state variable
  • function getName() public view returns(string memory)
    • view: this keyword means the function cannot change the blockchain state, which mainly used for query

Compile HelloWorld Contract#

Step1. Creat new directory for HelloWorld project

mkdir HelloWorld && cd HelloWorld

Step2. Init project

alaya-truffle init

After the command is executed, project directory structure is as follows:

  • Contracts/: solidity contract directory

  • Migrations/: depoly file directory

  • Test/: test script directory

  • Truffle-config.js: alaya-truffle config

Step3. Move HelloWorld contract compiled in to HelloWorld/contracts/

ls contracts/
  • HelloWorld.sol

Step4. Fix compile version same as the version setted in truffle-config.js

vim truffle-config.js

Truffle-config.js content is as follows:

compilers: {      solc: {            version: "^0.5.17",    // same as the version declared in HelloWorld.sol      }}

Step5. Compile contract

alaya-truffle compile

After the command is executed, project directory structure is as follows:

  • Build/: solidity contract directory after compiled

  • Build/contracts/HelloWorld.json:the compiled file corresponding with HelloWorld.sol

Deploly HelloWorld Contract#

Step1. Create deploy script

cd migrations/ && touch 2_initial_helloworld.js

Suggest replacing script name with contract name, for example the deploy script of HelloWorld contract :2_initial_helloworld.js,content is as follows:

const helloWorld = artifacts.require("HelloWorld"); //artifacts.require specify deployment contract    module.exports = function(deployer) {       deployer.deploy(helloWorld); //Failed to deploy contract with parameters, please refer to FAQ};

Step2. Setting config information for blockchain in truffle-config.js

vim truffle-config.js

Set blockchain network info

networks: {    development: {       host: "10.1.1.6",     // blockchain server address       port: 8806,            // server port       network_id: "*",       // Any network (default: none)       from: "atp1jtfqqqr6436ppj6ccnrh8xjg7qals3ctnnmurp", //the accout address of deploying contract       gas: 999999,       gasPrice: 50000000004,    },}

step3. Unlock wallet account

Enter the alaya-truffle console

alaya-truffle console

Import the private key (you can skip this step if you have already imported it)

web3.platon.personal.importRawKey("Your wallet private key","Your wallet password");

After importing successfully, you will see the address corresponding to the private key as follows:

'atp1jtfqqqr6436ppj6ccnrh8xjg7qals3ctnnmurp'

Unlock wallet account

 web3.platon.personal.unlockAccount('Your wallet address','Your wallet password',999999);

After unlocking successfully, you will see the following information:

ture

Step4. Deploy contract

alaya-truffle migrate

After deploying successfully, you will see log info as follows:

2_initial_helloworld.js======================
   Deploying 'HelloWorld'   ----------------------   > transaction hash:    0x87cd48cc467f9bc943fd096c57c8a7e7b7fa941380538d9e59797800c6c4292c   > Blocks: 0            Seconds: 0   > contract address:    atp1c5xxup4au4pqkgkm6a3p6hj3x0vvekdj52z2la   > block number:        282520   > block timestamp:     1585535169200   > account:             atp1jtfqqqr6436ppj6ccnrh8xjg7qals3ctnnmurp   > balance:             16447231233352977496646259638377769924557918764752765436645.336513079692286014   > gas used:            145569   > gas price:           1 gvon   > value sent:          0 ATP   > total cost:          0.000145569 ATP

   > Saving migration to chain.   > Saving artifacts   -------------------------------------   > Total cost:          0.000145569 ATP
Summary=======> Total deployments:   2> Final cost:          0.000259892 ATP

Call HelloWorld Contract#

Step1. Enter the alaya-truffle console

alaya-truffle console
  • You can execute command in alaya-truffle console

Step2. Create contract object

var abi = [{"constant":false,"inputs":[{"internalType":"string","name":"_name","type":"string"}],"name":"setName","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getName","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"}]; //you can refet to HelloWorld/build/contracts/HelloWorld.json
var contractAddr = 'atp1c5xxup4au4pqkgkm6a3p6hj3x0vvekdj52z2la';//contract addressvar helloWorld = new web3.platon.Contract(abi,contractAddr);  

Description:

  • abi the interface provided by the contract to external calls, the abi in the file compiled :HelloWorld/build/contracts/HelloWorld.json
  • contractAddr contract address
  • helloWorld contract object created

Step3. Call contract

helloWorld.methods.setName("hello world").send({from: 'atp1jtfqqqr6436ppj6ccnrh8xjg7qals3ctnnmurp'}).on('receipt', function(receipt) {console.log(receipt);}).on('error', console.error);

Description:

  • helloWorld the contract object created
  • methods specify the call method
  • setName the function of the HelloWorld contract, which has a parameter as hello world
  • from the address of caller
  • on listen to the result of the contract method executed. If failed, it will print the error info. If succeeds ,the console will print the receipt as belows:
{   blockHash:'0x3ae287d1e745e30d0d6c95d5220cc7816cda955e7b2f013c6a531ed95028a794', //the hash of block the transaction located  blockNumber: 159726,   contractAddress: null,  cumulativeGasUsed: 44820,  from: 'atp1jtfqqqr6436ppj6ccnrh8xjg7qals3ctnnmurp', //the address of caller  gasUsed: 44820, //gas cost  logsBloom:   '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',  status: true,  to: 'atp1c5xxup4au4pqkgkm6a3p6hj3x0vvekdj52z2la', //contract address  transactionHash:'0xb7a41f72d555d4a2d9f2954fbdc5bbbb4c5ce89c836f8704276419ed416b3866',   transactionIndex: 0,  events: {} }

Step4. Query contract

helloWorld.methods.getName().call(null,function(error,result){console.log("name is:" + result);})  

Description:

  • helloWorld the contract object created
  • methods specify the call method
  • getName the function of the HelloWorld contract, which has no parameter
  • call specify query method
  • function callback result,we can use console.log to print info.

Crowdfunding Contract#

Introduction#

In the following example, we will use smart contract for a crowdfunding campaign. The creator of the contract started crowdfunding, and initialized the number of tokens and the duration of the crowdfunding. If the crowdfunding is completed within a specified time, the crowdfunding will be successful. If the crowdfunding switch is turned off, a certain number of tokens based on a fixed exchange rate will be cast and credited to the name of the investor. Otherwise, the crowdfunding fails and the amount of the crowdfunding is returned to the investors.

There are two roles in the contract

  • Crowdfunder
  • Investor

Crowdfunding Process#

  • 1.Creating a crowdfunding contract refers to the beneficiary.
  • 2.Deployment crowdfunding contract initializes the number and duration of crowdfunding tokens.
  • 3.Investors invest.
  • 4.Determine if crowdfunding is over.
    • If the crowdfunding time is not up and the number of crowdfunding tokens has been completed, turn off the crowdfunding switch, investors will be allocated tokens in proportion. Crowdfunding success.
    • If the crowdfunding time is up and the amount of crowdfunding tokens has been completed, investors will be allocated tokens in proportion. Crowdfunding success.
    • If the crowdfunding time is up and the number of crowdfunding tokens is not completed, the investor tokens will be returned. Crowdfunding failure.

Crowdfunding Contract#

pragma solidity ^0.5.17;
contract CrowdFunding {    address payable public beneficiaryAddress = address(0x0); //Beneficiary address, set as contract creator    uint256 public fundingGoal = 100 atp;  //Crowdfunding target, unit is ATP    uint256 public amountRaised = 0; //The amount of money raised,the unit is VON    uint256 public deadline;     uint256 public price;  //token price    bool public fundingGoalReached = false;  //Achieving crowdfunding goals flag    bool public crowdsaleClosed = false; //Crowdfunding closed
    mapping(address => uint256) public balance; //Save the amount raised by the investor        mapping(address => uint256) public tokenMap; //Save the number of tokens owned by the investor
    //Record received ATP notifications    event GoalReached(address _beneficiaryAddress, uint _amountRaised);
    //Transfer notice    event FundTransfer(address _backer, uint _amount, bool _isContribution);        //Check if the address is empty    modifier validAddress(address _address) {        require(_address != address("atx1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq89qwkc") || _address != address("atp1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqdruy9j"));        _;    }
    /**     * Initialization constructor     *     * @param _fundingGoalInlats: Total crowdfunding ATP coin     * @param _durationInMinutes: Crowdfunding deadline, unit is minute     */    constructor (        uint _fundingGoalInlats,        uint _durationInMinutes    )public {        beneficiaryAddress = msg.sender;        fundingGoal = _fundingGoalInlats * 1 atp;        deadline = now + _durationInMinutes * 1 minutes;        price = 500 finney; //1个ATP币可以买 2 个代币    }

    /**     * fallback functioin     *     * you can send money directly to the contract     */    function () payable external {
        //check whether to close crowdfunding        require(!crowdsaleClosed);        uint amount = msg.value;
        //investor amount accumulated        balance[msg.sender] += amount;
        //Total invest accumulated        amountRaised += amount;
        //Transfer operation, how many tokens are transferred to the investor        tokenMap[msg.sender]  += amount / price;                emit FundTransfer(msg.sender, amount, true);    }
    /**     * Determine if the crowdfunding deadline has passed     */    modifier afterDeadline() { if (now >= deadline) _; }
    /**     * Check if the crowdfunding goal has been reached     */    function checkGoalReached() public afterDeadline payable{        if (amountRaised >= fundingGoal){            //crowdfunding goal has been reached            fundingGoalReached = true;            emit GoalReached(beneficiaryAddress, amountRaised);        }
        //Closing crowdfunding        crowdsaleClosed = true;    }

    /**     * Recover funds     *     * Check if the target or time limit has been reached, and if so, send the full amount to the beneficiary.     * If the goal is not reached, each investor can return the amount they invested     */    function safeWithdrawal() public afterDeadline {
        //If the crowdfunding goal is not reached        if (!fundingGoalReached) {            //Get the contracted caller's donated balance            uint amount = balance[msg.sender];
            if (amount > 0) {                //Returns all balances of the contract initiator                msg.sender.transfer(amount);                emit FundTransfer(msg.sender, amount, false);                balance[msg.sender] = 0;            }        }
        //f the crowdfunding goal is achieved and the contract caller is the beneficiary        if (fundingGoalReached && beneficiaryAddress == msg.sender) {
            //Give all donations from the contract to the beneficiary            beneficiaryAddress.transfer(amountRaised);                        emit FundTransfer(beneficiaryAddress, amountRaised, false);        }    }}

Compile Crowdfunding Contract

Step1. Create new directory for Crowdfunding project

mkdir myCrowdFunding && cd myCrowdFunding

The following commands are performed in the myCrowdFunding directory without special instructions.

Step2. Init project

alaya-truffle init

After the command is executed, project directory structure is as follows:

  • contracts/: solidity contract directory
  • migrations/: depoly file directory
  • test/: test script directory
  • truffle-config.js: alaya-truffle config

Step3. Move crowdfunding contract compiled in to myCrowdFunding/contracts/

ls myCrowdFunding/contracts/

Files in the directory: crowdFunding.sol.

Step4. Fix compile version same as the version setted in truffle-config.js

vim truffle-config.js

Truffle-config.js content is as follows:

compilers: {     solc: {        version: "0.5.17",    //same as the version declared in CrowdFunding.sol    }}

Step5. Compile contract

alaya-truffle compile

After the command is executed, project directory structure is as follows:

  • build/: solidity contract directory after compiled
  • build/contracts/CrowdFunding.json: the compiled file corresponding with CrowdFunding.sol

Deploly crowdfunding Contract

Step1. Create deploy script

cd migrations/ && touch 2_initial_CrowdFunding.js

Deploy script 2_initial_crowdFunding.js,content is as follows:

const CrowdFunding = artifacts.require("CrowdFunding"); //deployment contract class namemodule.exports = function(deployer) {      deployer.deploy(CrowdFunding,1000000,100);};

Step2. Setting config information for blockchain in truffle-config.js

vim truffle-config.js

Set blockchain network info

networks: {    development: {       host: "10.1.1.6",     // blockchain server address       port: 8806,            // server port       network_id: "*",       // Any network (default: none)       from: "atp1jtfqqqr6436ppj6ccnrh8xjg7qals3ctnnmurp", //the accout address of deploying contract       gas: 999999,       gasPrice: 50000000004,    },}

Step3. Deploy contract

alaya-truffle migrate

After deploying successfully, you will see log info as follows:

Compiling your contracts... Everything is up to date, there is nothing to compile. 3_initial_CrowdFunding.js     Deploying 'CrowdFunding'     transaction hash:    0x3a6419cd4169d7cfb430a1fc5632239ac4a01845827f20df9b3229a334c5488b     Blocks: 0            Seconds: 0     contract address:    atp1crcjuu9uwa9aukmf5dr5tq4ym6cv2kre0042ya //contract address     block number:        280532     block timestamp:     1581751224032     account:             atp1jtfqqqr6436ppj6ccnrh8xjg7qals3ctnnmurp     balance:             90000000.806077629992489796     gas used:            379154     gas price:           50.000000004 gVON     value sent:          0 ATP     total cost:          0.018957700001516616 ATP      Saving migration to chain.     Saving artifacts     Total cost:     0.018957700001516616 ATP

Crowdfounding Query:

Step1. Enter the alaya-truffle console

alaya-truffle console

You can execute command in alaya-truffle console

Step2. Create contract object

var abi = [...]; //ABI of CrowdFunding contract,can get from build/contracts/CrowdFunding.jsonvar contractAddr = 'atp1crcjuu9uwa9aukmf5dr5tq4ym6cv2kre0042ya'; //CrowdFundsing contract addressvar crowdFunding = new web3.platon.Contract(abi,contractAddr);

Step3. Query the amount raised

crowdFunding.methods.amountRaised().call(null,function(error,result){console.log("result:" + result);}); //query the amount raised

Step4. Crowdfunder judge the success of crowdfunding

crowdFunding.methods.safeWithdrawal().send({from:'atp1jtfqqqr6436ppj6ccnrh8xjg7qals3ctnnmurp'}).on('data', function(event){ console.log(event);}).on('error', console.error); 

Call contract command description:

  • crowdFunding is the contract object we built earlier
  • methods fixed syntax specifying that methods in the contract will be obtained
  • safeWithdrawal is a method in our crowdfunding contract to recover funds
  • from caller's wallet address
  • on listen for contract processing result events, and output error logs for failures

FAQ#

About Compile#

  1. How many commands in alaya-truffle?

    Refer to alaya-truffle develop guide Reference here.

  2. Why contract syntax cannot be verified?

    Solidity 0.4.x has a great different with 0.5.x, detail info refer to Reference here.

  3. Why truffle doesn't compile?

    Confirm the contract version same as the version specified in the truffle-config.js. Contract syntax be writed in a wrong way.

  4. Why the contract can not be deployed by truffle migrate?

    Confrim the blockchain network info be configured correctly. Confirm the account address be configured correctly.

  5. Deploying a contract with a parameter constructor using the command truffle migrate failed.

    For example, A.sol

    Constructor(uint256 a, string memory b, string memory c) public {}

    2_initial_A.js configured as follow:

    const A = artifacts.require("A");  module.exports = function(deployer) {        deployer.deploy(A,100,'PLA','PLAT');//pass the corresponding construction parameters};