Deploy a Smart Contract

In this chapter we will deploy an HRC20 token smart contract on Htmlcoin. All HRC20 compliant token contracts support a common set of methods:

contract HRC20 {

function totalSupply() constant returns (uint totalSupply);

function balanceOf(address _owner) constant returns (uint balance);

function transfer(address _to, uint _value) returns (bool success);

function transferFrom(address _from, address _to, uint _value) returns (bool success);

function approve(address _spender, uint _value) returns (bool success);

function allowance(address _owner, address _spender) constant returns (uint remaining);


event Transfer(address indexed _from, address indexed _to, uint _value);

event Approval(address indexed _owner, address indexed _spender, uint _value); }

}

Because all tokens share the same interface, it is much easier for wallets and exchanges to support all the different tokens out there in the wild.

In what follows, we will deploy the CappedToken, implemented by OpenZeppelin. We won't need to modify the contract in any way to make it work on Htmlcoin.

The CappedToken is an ERC20 compliant token, inheriting the basic functionalities from both StandardToken and MintableToken.

In particular,

  • StandardToken implements the ERC20 interface.

  • MintableToken adds the mint(address _to, uint256 _amount) method, to create new tokens out of thin air.

  • CappedToken adds limit to the max supply of tokens that could be minted.

ERC20

Create the project directory, and clone the zeppelin-solidity repository to the project directory:

mkdir mytoken && cd mytoken

git clone https://github.com/OpenZeppelin/openzeppelin-solidity.git

The Owner Address

The HRC20 token we deploy will be "owned" by a particular UTXO address. A few administrative methods are protected, such that only the owner of the contract may use them.

These methods are protected by the onlyOwner modifier, which checks whether the msg.sender is the contract's owner:

modifier onlyOwner() {

require(msg.sender == owner);

_;

}

For example, the method mint makes sure that only the owner can use it:

function mint(address _to, uint256 _amount) onlyOwner canMint public returns (bool)

Create The Owner Address And Fund It

Let's generate an address to act as the owner.

htmlcoin-cli getnewaddress

HaNR3sSnDeCY4Ek7VCZG1J9hQ3isGZ4oKw

There's nothing special about this address. You could use the address of any UTXO in your wallet.

Let's fund the owner address with 10 HTML, to pay for gas when we deploy our contract later:

htmlcoin-cli sendtoaddress HaNR3sSnDeCY4Ek7VCZG1J9hQ3isGZ4oKw 10

cf652f54e6a6dde3e60fa4e38eee1c529bf4ecf3f8424c7ac7ef9717850cc984

After the payment confirms, you should that there is one UTXO for this owner address:

htmlcoin-cli listunspent 1 99999 '["HaNR3sSnDeCY4Ek7VCZG1J9hQ3isGZ4oKw"]'

[

{

"txid": "cf652f54e6a6dde3e60fa4e38eee1c529bf4ecf3f8424c7ac7ef9717850cc984",

"vout": 1,

"address": "HaNR3sSnDeCY4Ek7VCZG1J9hQ3isGZ4oKw",

"account": "",

"scriptPubKey": "76a91437158152a9768477770ecb7a9e55a5875b9f35b088ac",

"amount": 10.00000000,

"confirmations": 1,

"spendable": true,

"solvable": true

}

]

Finally, we'll need to configure the deployment tool solar to use this particular address as the owner:

export HTMLCOIN_SENDER=HaNR3sSnDeCY4Ek7VCZG1J9hQ3isGZ4oKw

It takes quite a few steps to deploy a contract:

  1. Use the solidity compiler to compile the contract into bytecode.

  2. ABI encode the _capacity parameter into bytes.

  3. Concatenate 1 and 2 together, then make a createcontract RPC call to htmlcoind.

  4. Wait for transaction to confirm.

  5. Record the address of the contract, and owner of the contract, for later uses.

The solar Smart Contract deployment tool (included in the container) handles all of this for you.

Deploy Contract

To deploy the CappedToken contract, specifying 21 million as the capacity by passing in the constructor parameters as a JSON array (remember to set HTMLCOIN_SENDER):

solar deploy openzeppelin-solidity/contracts/token/ERC20/ERC20.sol:testtoken '["JIMMY","JIM"]'

Then solar waits for confirmation:

🚀 All contracts confirmed

deployed openzeppelin-solidity/contracts/token/ERC20/CappedToken.sol =>

a778c05f1d0f70f1133f4bbf78c1a9a7bf84aed3

The contract had been deployed to a778c05f1d0f70f1133f4bbf78c1a9a7bf84aed3. (You'd get a different contract address).

The solar status command lists all contracts that had been deployed with solar:

solar status


openzeppelin-solidity/contracts/token/ERC20/ERC20.sol

txid: 76601739d6bab94da25a805d4b154e7596ddc1d0baa30983094993db52208a18

address: 748ea3d187116d6cd6dc662f1194465293e2172a

confirmed: true

owner: HaNR3sSnDeCY4Ek7VCZG1J9hQ3isGZ4oKw

Note that the contract's owner should be set to the HTMLCOIN_SENDER value we have specified earlier. If you did not set QTUM_SENDER to anything, a random UTXO from the wallet is selected, and that become the owner.

You can find more information about the deployed contracts in solar.development.json.