• background
  • The premise condition
  • Deployment of smart contracts
  • Interact with smart contracts
  • Matters needing attention

background

Once you have created your own blockchain on QtumX, you can develop and publish smart contracts to provide blockchain-based applications. Since the established blockchain is a private chain or alliance chain, smart contract applications do not need to consume tokens on the public chain, which greatly saves the development cost. QtumX, like Qtum, supports EVM for Ethereum VMS. Thus, all Solidity based smart contract code can run directly on QtumX.

The premise condition

Install QtumX, and publish your own private chain, private chain construction tutorial. This article describes the deployment and interaction of smart contracts under the Qtum – Qt client, built on the qtum private chain and requiring some simple command-line operations, the demo opted for the solidity classic vote demo.

Deployment of smart contracts

  1. Start qtum-qt to enter the private chain environment, and start mining by using setpoaminer command from qtum-Qt’s help-debug window-console (mining must be started otherwise new blocks cannot be generated, smart contracts cannot be recorded and deployed to the private chain).
  2. Write Solidity smart Contract code with the option of online IDE Remix. Here are a few tutorials on how to write solidity:
  3. Official Solidity Document (Chinese translation optional)
  4. Solidity Tutorial Chinese version
  5. Qtum Smart contract usage and instructions
  6. We provide a Ballot Ballot demo, source code is as follows:

    Pragma solidity ^ 0.4.0; contract Ballot { struct Voter { uint weight; bool voted; uint8 vote; address delegate; } struct Proposal { uint voteCount; } address chairperson; mapping(address => Voter) voters; Proposal[] proposals; /// Create a new ballot with $(_numProposals) different proposals.function Ballot(uint8 _numProposals) public {
         chairperson = msg.sender;
         voters[chairperson].weight = 1;
         proposals.length = _numProposals;
     }
    
     /// Give $(toVoter) the right to vote on this ballot.
     /// May only be called by $(chairperson).
     function giveRightToVote(address toVoter) public {
         if(msg.sender ! = chairperson || voters[toVoter].voted)return;
         voters[toVoter].weight = 1;
     }
    
     /// Delegate your vote to the voter $(to).
     function delegate(address to) public {
         Voter storage sender = voters[msg.sender]; // assigns reference
         if (sender.voted) return;
         while(voters[to].delegate ! = address(0) && voters[to].delegate ! = msg.sender) to = voters[to].delegate;if (to == msg.sender) return;
         sender.voted = true;
         sender.delegate = to;
         Voter storage delegateTo = voters[to];
         if (delegateTo.voted)
             proposals[delegateTo.vote].voteCount += sender.weight;
         else
             delegateTo.weight += sender.weight;
     }
    
     /// Give a single vote to proposal $(toProposal).
     function vote(uint8 toProposal) public {
         Voter storage sender = voters[msg.sender];
         if (sender.voted || toProposal >= proposals.length) return;
         sender.voted = true;
         sender.vote = toProposal;
         proposals[toProposal].voteCount += sender.weight;
     }
    
     function winningProposal() public constant returns (uint8 _winningProposal) {
         uint256 winningVoteCount = 0;
         for (uint8 prop = 0; prop < proposals.length; prop++)
             if(proposals[prop].voteCount > winningVoteCount) { winningVoteCount = proposals[prop].voteCount; _winningProposal = prop; }}}Copy the code
  7. Convert the source code to bytecode and ABI required in qtum qt, find Compile in the right sidebar of Remix, click Details (select “Object” in Bytecode to copy, only need to enter this item) to view and copy. Here is the compiled Bytecode and ABI:
  8. The bytecode:
608060405234801561001057600080fd5b50604051602080610487833981016040908152905160008054600160a060020a0319163317808255600160 a060020a03168152600160208190529290209190915560ff8116610060600282610067565b50506100b1565b81548183558181111561008b57600083 81526020902061008b918101908301610090565b505050565b6100ae91905b808211156100aa5760008155600101610096565b5090565b90565b6103 c7806100c06000396000f3006080604052600436106100615763ffffffff7c0100000000000000000000000000000000000000000000000000000000 6000350416635c19a95c8114610066578063609ff1bd146100895780639e7b8d61146100b4578063b3f98adc146100d5575b600080fd5b3480156100 7257600080fd5b50610087600160a060020a03600435166100f0565b005b34801561009557600080fd5b5061009e610250565b6040805160ff909216 8252519081900360200190f35b3480156100c057600080fd5b50610087600160a060020a03600435166102bb565b3480156100e157600080fd5b5061 008760ff6004351661031b565b33600090815260016020819052604082209081015490919060ff16156101155761024b565b5b600160a060020a0383 811660009081526001602081905260409091200154620100009004161580159061016d5750600160a060020a03838116600090815260016020819052 60409091200154620100009004163314155b1561019f57600160a060020a039283166000908152600160208190526040909120015462010000900490 921691610116565b600160a060020a0383163314156101b55761024b565b506001818101805460ff1916821775ffffffffffffffffffffffffffffff ffffffffff0000191662010000600160a060020a0386169081029190911790915560009081526020829052604090209081015460ff16156102435781 546001820154600280549091610100900460ff1690811061022c57fe5b60009182526020909120018054909101905561024b565b815481540181555b 505050565b600080805b60025460ff821610156102b6578160028260ff1681548110151561027557fe5b906000526020600020016000015411156102 ae576002805460ff831690811061029a57fe5b906000526020600020016000015491508092505b600101610255565b505090565b600054600160a060 020a0316331415806102f15750600160a060020a0381166000908152600160208190526040909120015460ff165b156102fb57610318565b600160a0 60020a0381166000908152600160208190526040909120555b50565b3360009081526001602081905260409091209081015460ff1680610344575060 025460ff831610155b1561034e57610397565b6001818101805460ff191690911761ff00191661010060ff8516908102919091179091558154600280 5491929091811061038457fe5b6000918252602090912001805490910190555b50505600a165627a7a723058200864fb02ff362bbc06e105162a9fcb fe289feff2354dbe84cf794f1fb2ec38d60029Copy the code
  • ABI:
[{"constant": false."inputs": [{"name": "to"."type": "address"}]."name": "delegate"."outputs": []."payable": false."stateMutability": "nonpayable"."type": "function"
    },
    {
        "constant": true."inputs": []."name": "winningProposal"."outputs": [{"name": "_winningProposal"."type": "uint8"}]."payable": false."stateMutability": "view"."type": "function"
    },
    {
        "constant": false."inputs": [{"name": "toVoter"."type": "address"}]."name": "giveRightToVote"."outputs": []."payable": false."stateMutability": "nonpayable"."type": "function"
    },
    {
        "constant": false."inputs": [{"name": "toProposal"."type": "uint8"}]."name": "vote"."outputs": []."payable": false."stateMutability": "nonpayable"."type": "function"
    },
    {
        "inputs": [{"name": "_numProposals"."type": "uint8"}]."payable": false."stateMutability": "nonpayable"."type": "constructor"}]Copy the code
  1. Deploy smart contracts to the private chain via qtum- Qt. Select Smart Schemation-Create in the graphical interface and paste the Bytecode and ABI into their respective positions; The Demo needs to initialize _numProposal of the Uint8 type, which needs to be filled in when deploying smart contracts. After initializing the parameters, we click the CREATE CONTRACT button in the lower right corner. After successful deployment, Result will be returned, in which we can see the transaction ID, SenderAddress of the deployer and ContractAddress of the CONTRACT (used to interact with the smart CONTRACT).






  1. After the deployment is complete, you can see that the corresponding block information is written in Transactions, which will consume Gas.



Interact with smart contracts

  1. After the deployment of Smart Contracts is completed, we can interact with Smart Contracts with Send To and Call under Smart Contracts. Since there are no new nodes and users in the private chain environment, we can switch to the main chain and use the getNewAddress command in Debug Window to generate several new addresses for simulation. Later we can add the real user address (note: The generated address is not the hexadecimal that the contract needs to pass in. You can get the hexadecimal of the address in the Debug Window by using gethexAddress $address without the 0x prefix.
  2. In the Call Contract, you can Call the relevant parameters returned by the functions in the smart Contract. You can view them by entering the Contract address and the ABI corresponding to the parameters you want to view. All calculations of the Call operation are performed in the chain without consuming Gas. The winningProposal that can be viewed in the demo is the result of the winning vote. We have not written any data yet, and the winning vote returns the default value 0. (the (00) in Function is used to pass Value to smart Contract, which is Qtum in Qtum network and can be ignored in Call Contract)



  1. The corresponding position in Send To is pasted into the contract address and ABI, and the function of the smart contract can be called. Send To will pass parameters To the smart contract and write data, and calculation and storage will be carried out on the chain, so Gas will be consumed. In this case, (00) can be used to pass the QTUM to the smart contract. You can also write the destruction address in the smart contract, and the QTUM will be returned to the account after the smart contract is declared destroyed by the owner.



  1. Several functions let’s make a brief introduction:
  2. The giveRightToVote function can only be called by the chairman to deliver voting rights. The Chairman is the address where the smart contract is deployed, and the weight +1 of the address that gets the voting rights.
  3. Delegate function is called by the address that has the right to vote. It can delegate its voting rights to the specified address and record the delegate variable. If the voting rights of the address that is delegated have also been delegated to other addresses, the voting rights are now concentrated on the final entruster.
  4. The vote function is called by the address that has the right to vote. After voting, it sets its own voting weight -1 and voteCount +1 of the Proposal that is voted.
  5. WinningProposal Traverses the candidate proposal array, returns the array subscript (number) of voteCount’s largest proposal, and realizes viewing the winner of the vote.

Matters needing attention

  • Do not forget to set up mining nodes during the deployment and interaction of smart contracts.
  • In Remix, select the matching solidity version for compilation to avoid compilation errors due to incompatible versions.
  • After deploying smart contracts, you need to wait for confirmation to interact with them. You can enter getAccountInfo $CONTRACT in the Debug Window or view smart contracts in the Transaction list.
  • New addresses are generated in the main chain and converted to hexadecimal without the 0x prefix when interacting with the smart contract.
  • Deployment of smart contract and send to need to consume GAS. If it is a test, transfer can be made to the address to be operated first and appropriate QTUM can be reserved as GAS.