在 Cardano KEVM Testnet 測試網路中部署智能合約

in #cardano6 years ago

0、Cardano KEVM/IELE Testnet 相關參考資料,請參考之前的文章:

https://steemit.com/cardano/@oneleo/cardano-kevm-iele-testnet
https://steemkr.com/cardano/@oneleo/cardano-kevm-iele-testnet

1、如何安裝 Oracle VM VirtualBox 5.2.16 版,請參考之前的文章:

https://steemit.com/oracle/@oneleo/oracle-vm-virtualbox-5-2-16
https://steemkr.com/oracle/@oneleo/oracle-vm-virtualbox-5-2-16

2、如何在 Oracle VM VirtualBox 內安裝 Ubuntu 18.04 Desktop 版,並安裝更新、建立快照,請參考之前的文章:

https://steemit.com/vm/@oneleo/oracle-vm-virtualbox-ubuntu-18-04-desktop
https://steemkr.com/vm/@oneleo/oracle-vm-virtualbox-ubuntu-18-04-desktop

3、如何在 Ubuntu 作業系統內安裝 Cardano Testnet 測試網路輕量級錢包 Mallet,請參考之前的文章:

https://steemit.com/cardano/@oneleo/ubuntu-linux-cardano-testnet-mallet
https://steemkr.com/cardano/@oneleo/ubuntu-linux-cardano-testnet-mallet

4、如何使用 Cardano 輕量級錢包 Mallet 連接進 KEVM Testnet 測試網路並進行轉帳測試,請參考之前的文章:

https://steemit.com/cardano/@oneleo/cardano-mallet-kevm-testnet
https://steemkr.com/cardano/@oneleo/cardano-mallet-kevm-testnet

5、在 Cardano KEVM Testnet 測試網路中部署智能合約

(1)使用瀏覽器進入 Solidity 線上編譯工具 Remix:
https://remix.ethereum.org/

→ 點選左上角【+】「Create New File in the Browser Storage Explorer」。

(2)在「File Name」中輸入【example.sol】→【OK】

(3)輸入以下程式碼 → 在右側「Compile」標籤中 → 點選【Start to Compile】。

pragma solidity ^0.4.24;
contract Example {
    uint256 public num = 1;
    function setNum(uint256 _num) public {
        num = _num;
    }
}

(5)Compile 完畢後,點選右側的【Details】鈕。

(6)在「BYTECODE」中點選【複製】圖示(Copy value to clipboard)。

(7)回到 Ubuntu 18.04.1 VM 的 Terminal,並將剛才複製的值貼入

$ cd $HOME/mallet
$ ./mallet kevm

// 選定第一組 Testnet Wallet 帳號。
mallet> selectAccount('0x5bcf00ecb86c5b833549fcc68e32650e21c58559')

// 設置智能合約變數,只需將 Remix 線上編譯器編譯後的 Bytecode 貼入即可。
mallet> runtimeBytecode =
{ "linkReferences": {}, "object": "6080604052600160005534801561001557600080fd5b5060dc806100246000396000f3006080604052600436106049576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680634e70b1dc14604e578063cd16ecbf146076575b600080fd5b348015605957600080fd5b50606060a0565b6040518082815260200191505060405180910390f35b348015608157600080fd5b50609e6004803603810190808035906020019092919050505060a6565b005b60005481565b80600081905550505600a165627a7a72305820d8ded92d4cce9640342ef969f28845bc7c54913fe6f7b418a64c8e065822ca140029", "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x1 PUSH1 0x0 SSTORE CALLVALUE DUP1 ISZERO PUSH2 0x15 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0xDC DUP1 PUSH2 0x24 PUSH1 0x0 CODECOPY PUSH1 0x0 RETURN STOP PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH1 0x49 JUMPI PUSH1 0x0 CALLDATALOAD PUSH29 0x100000000000000000000000000000000000000000000000000000000 SWAP1 DIV PUSH4 0xFFFFFFFF AND DUP1 PUSH4 0x4E70B1DC EQ PUSH1 0x4E JUMPI DUP1 PUSH4 0xCD16ECBF EQ PUSH1 0x76 JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST CALLVALUE DUP1 ISZERO PUSH1 0x59 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x60 PUSH1 0xA0 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP3 DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH1 0x81 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x9E PUSH1 0x4 DUP1 CALLDATASIZE SUB DUP2 ADD SWAP1 DUP1 DUP1 CALLDATALOAD SWAP1 PUSH1 0x20 ADD SWAP1 SWAP3 SWAP2 SWAP1 POP POP POP PUSH1 0xA6 JUMP JUMPDEST STOP JUMPDEST PUSH1 0x0 SLOAD DUP2 JUMP JUMPDEST DUP1 PUSH1 0x0 DUP2 SWAP1 SSTORE POP POP JUMP STOP LOG1 PUSH6 0x627A7A723058 KECCAK256 0xd8 0xde 0xd9 0x2d 0x4c 0xce SWAP7 BLOCKHASH CALLVALUE 0x2e 0xf9 PUSH10 0xF28845BC7C54913FE6F7 0xb4 XOR 0xa6 0x4c DUP15 MOD PC 0x22 0xca EQ STOP 0x29 ", "sourceMap": "26:122:0:-;;;71:1;50:22;;26:122;8:9:-1;5:2;;;30:1;27;20:12;5:2;26:122:0;;;;;;;" }

// 只需智能合約變數中的 object 變數即可。
mallet> myContract = runtimeBytecode.object

//-------------------------Content-------------------------
'6080604052600160005534801561001557600080fd5b5060dc806100246000396000f3006080604052600436106049576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680634e70b1dc14604e578063cd16ecbf146076575b600080fd5b348015605957600080fd5b50606060a0565b6040518082815260200191505060405180910390f35b348015608157600080fd5b50609e6004803603810190808035906020019092919050505060a6565b005b60005481565b80600081905550505600a165627a7a72305820d8ded92d4cce9640342ef969f28845bc7c54913fe6f7b418a64c8e065822ca140029'
//-------------------------Content-------------------------

// 設置交易變數,用以部署智能合約,需符合下方 JSON 格式。
mallet> tx = {
    gas: 470000, // gas limit,必要值。
    data: myContract // 智能合約的二進制碼。
};

//-------------------------Content-------------------------
{ gas: 470000,
  data:
   '6080604052600160005534801561001557600080fd5b5060dc806100246000396000f3006080604052600436106049576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680634e70b1dc14604e578063cd16ecbf146076575b600080fd5b348015605957600080fd5b50606060a0565b6040518082815260200191505060405180910390f35b348015608157600080fd5b50609e6004803603810190808035906020019092919050505060a6565b005b60005481565b80600081905550505600a165627a7a72305820d8ded92d4cce9640342ef969f28845bc7c54913fe6f7b418a64c8e065822ca140029' }
//-------------------------Content-------------------------

// 執行智能合約部署交易。
mallet> deploymentHash = sendTransaction(tx)

//-------------------------Content-------------------------
Enter password: ubuntu
'0x2df522942ea21fe29c9eaefc507a4313a3d02ecadfd86ba74fcdffa6d5ea6df8'
//-------------------------Content-------------------------

// 取得 txHash 的交易資訊。
mallet> getReceipt(deploymentHash)

//-------------------------Content-------------------------
{ transactionHash:
   '0x2df522942ea21fe29c9eaefc507a4313a3d02ecadfd86ba74fcdffa6d5ea6df8',
  transactionIndex: 0,
  blockNumber: 453507,
  blockHash:
   '0x33950e41e2cede1e49c91cfd28d090b02b1fea460b065892d6427d466c770f54',
  cumulativeGasUsed: 470000,
  gasUsed: 470000,
  contractAddress: '0x411dc3c87d3a0c5e27800810ccee920a13780870',
  logs: [],
  statusCode: '0x00',
  status: 1,
  returnData: '0x' }
//-------------------------Content-------------------------

// 取得智能合約地址。
mallet> myContractAddress = getReceipt(deploymentHash).contractAddress

//-------------------------Content-------------------------
'0x411dc3c87d3a0c5e27800810ccee920a13780870'
//-------------------------Content-------------------------

(8)待解問題:

a、要如何才能呼叫智能合約的函數呢?不能直接呼叫,仍需要使用外部的 ABI 才行。
參考:
https://forum.cardano.org/t/working-kevm-smart-contract-test-script/13137
https://github.com/antipalos/vivliothiki/tree/master/cardano-dev/kevm/testnet-web3

b、使用 Ethereum 以太坊官方 go-ethereum 呼叫智能合約會出現 no contract code at given address 錯誤
參考:如何使用 Golang 存取以太坊,請參考之前的文章:
https://steemit.com/go/@oneleo/windows-10-golang-rinkeby

package main

import (
    "fmt"
    "log"
    "go-ethereum-test/bin/cardano_contracts/example"
    "github.com/ethereum/go-ethereum/common"
    "github.com/ethereum/go-ethereum/ethclient"
)

func main() {
    client, err := ethclient.Dial("https://kevm-testnet.iohkdev.io:8546")
    if err != nil {
        log.Fatal(err)
    }

    contractAddress := common.HexToAddress("0x411dc3c87d3a0c5e27800810ccee920a13780870")

    instance, err := example.NewExample(contractAddress, client)
    if err != nil {
        log.Fatal(err)
    }

    num, err := instance.Num(nil)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println(num.String())
}

顯示訊息

API server listening at: 127.0.0.1:2345
time="2018-08-15T11:25:00+08:00" level=info msg="launching process with args: [q:\\GoDr\\Go\\oneleo\\src\\go-ethereum-test\\test\\debug]" layer=debugger
time="2018-08-15T11:25:01+08:00" level=debug msg=continuing layer=debugger
2018/08/15 11:25:14 no contract code at given address
time="2018-08-15T11:25:14+08:00" level=debug msg=halting layer=debugger

Donate ADA:
DdzFFzCqrhsup2Q4nnhKJJZ5BRuPkYUSPqDJn72t2dtHtVqsz5kQQmopMQR16Sv9qS5NC4w8Kv5P8XrDH2n2FD2akxtrntjc8hbgAmTz