部署智能合约到公链

简介: 以太坊公链除了主网,还有多个测试网络。主网(Mainnet)是正式的以太坊网络,里面的以太币是真正有价值的,测试网络中的以太币没有价值,只用于测试。我们最终目标是连接到主网,但先连接到测试网络Kovan,虽然本地区块链网络(Ganache)也能测试,但与公链还是有区别的。...

1. 连接公链

以太坊公链除了主网,还有多个测试网络。主网(Mainnet)是正式的以太坊网络,里面的以太币是真正有价值的,测试网络中的以太币没有价值,只用于测试。

我们最终目标是连接到主网,但先连接到测试网络Kovan,虽然本地区块链网络(Ganache)也能测试,但与公链还是有区别的。

连接到公链的步骤如下:

    1. 设置钱包来管理公链帐户
    2. 连接到以太坊节点
    3. 更新项目设置
    4. 访问以太坊节点

    1.1设置钱包

    首先需要设置一个钱包,来管理我们的公链帐户。

    简单起见,可以借用Ganache本地区块链钱包,由于区块链的工作原理,这个钱包在公共区块链和本地区块链上都是有效的。

    打开Ganache,主界面上可以看到一个名为“MNEMONIC”的部分:

    image.gif

    这是一个种子短语,用于构建由Ganache管理的钱包。我们可以使用这个种子短语加密重建钱包,来连接到公链。

    复制这个值,保存到一个秘密文件,MNEMONIC是一个秘密值,需要保密。在项目根目录中创建一个.env文件,保存MNEMONIC值,如下所示:

    MNEMONIC="你的mnemonic"

    image.gif

    1.2 连接以太坊节点

    现在已经创建了钱包,下一步需要访问Ethereum节点,以便连接到公共区块链网络。

    有几种方法可以做到这一点,可以使用Geth或Parity运行自己的Ethereum节点。但这需要从区块链下载大量数据并保持同步,很麻烦。

    比较方便的方法是,使用Infura访问Ethereum节点。Infura是一个免费提供Ethereum节点的服务。

    在Infura上注册账号,创建项目,在项目详情页上可以查看API KEY:

    image.gif

    使用API KEY,就可以访问以太坊网络节点。

    .env文件中添加Infura api key的配置:

    INFURA_API_KEY="https://kovan.infura.io/v3/543526cd4d3846acbc3826484e934564"
    MNEMONIC="你的mnemonic"

    image.gif

    1.3 更新项目设置

    接下来使用MNEMONICINFURA_API_KEY,更新项目的网络配置,以便连接到公共区块链网络。

    修改truffle-config.js文件:

    // 导入dotenv库创用于读取`.env`文件中的设置
    require('dotenv').config();
    // 导入truffle-hdwallet-provider库重建钱包
    const HDWalletProvider = require('truffle-hdwallet-provider');
    module.exports = {
      networks: {
        development: {
         host: "127.0.0.1",     // Localhost (default: none)
         port: 7545,            // Standard Ethereum port (default: none)
         network_id: "*",       // Any network (default: none)
        },
        // Useful for deploying to a public network.
        // NB: It's important to wrap the provider as a function.
        kovan: {
          provider: () => new HDWalletProvider(
            process.env.MNEMONIC, 
            process.env.INFURA_API_KEY
          ),
          gas: 5000000,
          gasPrice: 25000000000,
          network_id: 42
        },
      },
      solc: {
        optimizer: {
          enabled: true,
          runs: 200
        }
      }
    }

    image.gif

    可以看到,我们使用了.env配置文件中的MNEMONICINFURA_API_KEY配置了kovan网络。

    由于用到了dotenv与truffle-hdwallet-provider这2个库,我们需要先安装:

    切换到项目目录,执行以下命令

    npm install dotenv --save-dev

    image.gif

    npm install truffle-hdwallet-provider --save-dev

    image.gif

    注意 安装truffle-hdwallet-provider时,如果出现node-gyp相关的错误,可参考这里解决。

    1.4 访问以太坊节点

    使用truffle console连接到公共区块链网络:

    $ truffle console --network kovan

    image.gif

    要验证连接,可以从区块链中读取一些数据,获取一些关于最新区块的信息,在控制台上执行:

    web3.eth.getBlock('latest').then(console.log)

    image.gif

    输出:

    { author: '0x03801efb0efe2a25ede5dd3a003ae880c0292e4d',
      difficulty: '340282366920938463463374607431768211454',
      extraData:
       '0xde830206028f5061726974792d457468657265756d86312e33362e30826c69',
      gasLimit: '0x7a1200',
      gasUsed: '0x17d23',
      hash:
       '0xc7390c4f492c8c1da60608135fc9e05930123b645b39f221cba33d8b3c577b2a',
      logsBloom:
       '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000080000000000000000000100000008000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400800000000000010000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000008000000',
      receiptsRoot:
       '0x3d05bb2ed4fcc90234eea6d840e7d0e3ce7f598a15e5314536b17bcd11c78b5b',
      sealFields:
       [ '0x84175e8801',
         '0xb84155a8cdb108dccec1d314124058fa6f22e7400ee200db0a94b7b165e4c3454c1818cc05f815cb7ce48f7a88b8401515740311a3566d9cf079428d506a6daca50101' ],
      sha3Uncles:
       '0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347',
      signature:
       '55a8cdb108dccec1d314124058fa6f22e7400ee200db0a94b7b165e4c3454c1818cc05f815cb7ce48f7a88b8401515740311a3566d9cf079428d506a6daca50101',
      size: 877,
      stateRoot:
       '0x03af5adce52a81ce5d332cddb9955e344214bff00859b78868116e1e839efdf7',
      step: '392071169',
      timestamp: 1568284676,
      totalDifficulty: '4524524338444961608702071789512829094373049115',
      transactions:
       [ '0xded7fed0842fd65ec808bc3652ec4175bc190acc11345c49c44b1fb5d954610f',
         '0x7e9112a46fa3c07aad813ea86355b15eebb44023c040d198ee7d15d379bbc2be' ],
      transactionsRoot:
       '0x0dd10d90686dda2684bd0ba70d1c9e1d9a5302c30ca75eb2c5b07a7b6e4498b9',
      uncles: [] }

    image.gif

    可以看到,已经成功连接到了公链。

    2. 部署智能合约到公链

    现在,我们将智能合约部署到公链。步骤如下:

      1. 部署需要消耗Gas,获取测试以太币用于部署
      2. 部署智能合约
      3. 验证部署

      2.1获取测试以太币

      部署需要消耗Gas,Gas需要支付以太币,我们部署到的是公链测试网Kovan,网络中的以太币没有市场价值。

      可以从Kovan faucet Gitter聊天室获取测试用的伪以太币。只需把钱包地址发送出去,约5分钟内,有人会给你发测试用的伪以太币。

      打开Ganache并复制列表中第一个帐户的地址(钱包地址),类似下面所示:

      0x29920e756f41F8e691aE0b12D417C19204371E91

      image.gif

      发送到聊天室内,稍等片刻,你的账号将收到一笔以太币。

      2.2 部署智能合约

      现在帐户里已经有了资金,可以进行部署了。

      执行部署命令:

      truffle migrate --network kovan

      image.gif

      一旦部署完成,应该会看到部署成功的消息。

      部署命令执行详情:

      G:\qikegu\ethereum\mydapp>truffle migrate --network kovan
      Compiling your contracts...
      ===========================
      > Everything is up to date, there is nothing to compile.
      Migrations dry-run (simulation)
      ===============================
      > Network name:    'kovan-fork'
      > Network id:      42
      > Block gas limit: 0x7a1200
      ...
      Starting migrations...
      ======================
      > Network name:    'kovan'
      > Network id:      42
      > Block gas limit: 0x7a1200
      1_initial_migration.js
      ======================
         Deploying 'Migrations'
         ----------------------
         > transaction hash:    0x7e30b5c716afed45888a9dd2d6af7e6f52a9fade0346e8ad7d0c268de508a26a
         > Blocks: 2            Seconds: 9
         > contract address:    0x168A7247B58786edd259502948f5Bf9449C863AD
         > block number:        13447029
         > block timestamp:     1568294312
         > account:             0x29920e756f41F8e691aE0b12D417C19204371E91
         > balance:             2.993465175
         > gas used:            261393
         > gas price:           25 gwei
         > value sent:          0 ETH
         > total cost:          0.006534825 ETH
         > Saving migration to chain.
         > Saving artifacts
         -------------------------------------
         > Total cost:         0.006534825 ETH
      2_deploy_contracts.js
      =====================
         Deploying 'MyContract'
         ----------------------
         > transaction hash:    0xc1f7ec8fee1a23e3d08d0c9e9d6e15fef24feb8ba163e0071dccb1bb90cc0eca
         > Blocks: 0            Seconds: 0
         > contract address:    0x4D3CFaF8457CEA76c0409f989f9870115B4d2d82
         > block number:        13447036
         > block timestamp:     1568294340
         > account:             0x29920e756f41F8e691aE0b12D417C19204371E91
         > balance:             2.9850534
         > gas used:            294448
         > gas price:           25 gwei
         > value sent:          0 ETH
         > total cost:          0.0073612 ETH
         > Saving migration to chain.
         > Saving artifacts
         -------------------------------------
         > Total cost:           0.0073612 ETH
      Summary
      =======
      > Total deployments:   2
      > Final cost:          0.013896025 ETH
      Summary
      =======
      > Total deployments:   2
      > Final cost:          0.013896025 ETH

      image.gif

      2.3 验证部署

      现在打开truffle控制台,与kovan测试网络上的智能合约进行交互:

      $ truffle console --network kovan

      image.gif

      在控制台中执行:

      truffle(kovan)> MyContract.deployed().then((c) => { contract = c })

      image.gif

      然后:

      truffle(kovan)> contract.get()
      'myValue'
      truffle(kovan)> contract.set("hello world")
      { tx:
         '0x7bf63444f3a7bd70e981a7bd49228b1cf1a8c3754daf64c4c7765b8eee46bf37',
        receipt:
         { blockHash:
            '0xe03d0f43d85f4e41c18a90aa563ebda08899c6b9c38d0cd7779937046e2aed0c',
           blockNumber: 13447763,
           contractAddress: null,
           cumulativeGasUsed: 33629,
           from: '0x29920e756f41f8e691ae0b12d417c19204371e91',
           gasUsed: 33629,
           logs: [],
           logsBloom:
            '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
           root: null,
           status: true,
           to: '0x4d3cfaf8457cea76c0409f989f9870115b4d2d82',
           transactionHash:
            '0x7bf63444f3a7bd70e981a7bd49228b1cf1a8c3754daf64c4c7765b8eee46bf37',
           transactionIndex: 0,
           rawLogs: [] },
        logs: [] }
      truffle(kovan)> contract.get()
      'hello world'

      image.gif

      可以看到智能合约已经成功部署。

      3. truffle脚本

      Truffle包含一个脚本运行器,可对以太坊网络执行自定义脚本。

      让我们创建一个脚本并执行。

      在项目根目录下,创建script.js文件,内容如下:

      module.exports = function(callback) {
        web3.eth.getBlock('latest').then(console.log)
      }

      image.gif

      该脚本将从Kovan测试网络获取最新区块的信息。

      执行脚本:

      truffle exec script.js --network kovan

      image.gif

      输出:

      { author: '0x596e8221a30bfe6e7eff67fee664a01c73ba3c56',
        difficulty: '340282366920938463463374607431768211454',
        extraData:
         '0xde830205058f5061726974792d457468657265756d86312e33362e30826c69',
        gasLimit: '0x7a1200',
        gasUsed: '0x5e61',
        hash:
         '0x225a1e0b13fd20396af60d049ce9bb94c2f3f7df06c7db260880b62c91997004',
        logsBloom:
         '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
        miner: '0x596e8221A30bFe6e7eFF67Fee664A01C73BA3C56',
        number: 13448162,
        parentHash:
         '0x28d00fd7b66771130ed98de5073c7797ee293e7bee4b546793a4b79171555066',
        receiptsRoot:
         '0x44617b5733ee59bde159af08ffd6edae36e0964f1724c333f3d1bef0808dee15',
        sealFields:
         [ '0x84175e95d7',
           '0xb8412ed900e67f4a72925fb3b495efb3f547411f40d26e972cc0e8b2cf26e40cf84a545e0328199d4880b79c62670129a7db12ac58234bee0866c6376b46ab99e8a200' ],
        sha3Uncles:
         '0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347',
        signature:
         '2ed900e67f4a72925fb3b495efb3f547411f40d26e972cc0e8b2cf26e40cf84a545e0328199d4880b79c62670129a7db12ac58234bee0866c6376b46ab99e8a200',
        size: 797,
        stateRoot:
         '0xe1bbaacfb950361bec70f4ad53a2605e1ac1d2ff0bfd913fe063dc6c5f3252a0',
        step: '392074711',
        timestamp: 1568298844,
        totalDifficulty: '4525729278306228651801195598997744985609807728',
        transactions:
         [ '0xf1ae41eac6b32419bc62a6cde9cab4b4ca244899a3d49b4a2461bcf94f504176' ],
        transactionsRoot:
         '0xf08c8097ea946f84ce9594ce73648fc0f9f683adef105a5db00c5f1f15e61c2c',
        uncles: [] }

      image.gif

      下面的代码智能合约MyContract中,读取value值,将script.js脚本文件中的代码替换为:

      const MyContract = artifacts.require("./MyContract.sol");
      module.exports = async function(callback) {
        const contract = await MyContract.deployed()
        const value = await contract.get()
        console.log("Value:", value)
      }

      image.gif

      执行脚本:

      truffle exec script.js --network kovan

      image.gif

      输出:

      Value: hello world

      image.gif

      脚本运行器是一个非常有用的功能。

      目录
      相关文章
      |
      IDE Java 编译器
      浅析@SneakyThrows
      在日常的开发中,相信你一定使用过Lombok,它是一款开源的可用于Java平台的代码生成库。我们在定义JavaBean的时候,会使用IDE自动生成构造方法、getter、setter、equals、hashCode、toString等方法,一旦类的属性有修改就要重新生成,通过使用Lambok的简单注解来精简代码就能达到消除冗长代码的目的。
      954 0
      浅析@SneakyThrows
      |
      3月前
      |
      人工智能 Kubernetes 监控
      初探:从0开始的AI-Agent开发踩坑实录
      本文主要阐述作者通过亲身实践,探索利用AI Agent实现开源应用Helm Chart自动化生成的实践历程。
      657 18
      初探:从0开始的AI-Agent开发踩坑实录
      |
      存储 开发框架 JSON
      区块链开发必备的9个Rust包
      Rust是新一代的潜力巨大的开发语言。本文编辑整理了9个主流的用于以太坊、比特币、tendermint、eosio、polkadot等区块链开发的Rust包,可用于区块链应用的快速开发。
      2522 0
      |
      5月前
      |
      人工智能 关系型数据库 数据库
      在仓颉开发语言中使用数据库
      本文介绍了在仓颉开发语言中操作关系型数据库的流程,包括获取数据库、建表、增删改查等操作,并提供了详细的代码示例,帮助开发者快速掌握HarmonyOS下数据库的应用。
      |
      10月前
      |
      运维 Serverless 云计算
      解锁协作与创新的钥匙:计算巢&JupyterHub 引领数据驱动新时代
      在这个数字化转型的时代,JupyterHub 为教育、研究和企业提供了一种强大且灵活的解决方案,帮助团队和个人高效地协作和探索数据。无论您是数据科学家、教育工作者还是开发团队的一员,JupyterHub 都能通过其无与伦比的功能和易用性提升您的生产力和创新能力。计算巢提供
      |
      人工智能
      采用8个64B模型进行的模型融合,效果如何呢?
      【10月更文挑战第1天】论文解读:针对模型融合(Model Merging)中的AI模型数量、模型大小、模型能力、合并方法等因素的实验及结果
      343 2
      |
      前端开发 JavaScript
      vite中css最佳实践:使用postcss完善项目中的css配置
      【8月更文挑战第3天】使用postcss完善项目中的css配置
      3340 1
      |
      JSON 编解码 Rust
      Rust 模块化:深入了解 Rust 中的代码组织
      关键字`mod、pub、crate、self、super、use`都表示什么含义,如何使用?
      303 1
      |
      机器学习/深度学习 算法
      【OpenVI—视觉生产系列之视频插帧实战篇】几行代码,尽享流畅丝滑的视频观感
      随着网络电视、手机等新媒体领域的快速发展,用户对于观看视频质量的要求也越来越高。当前市面上所广为传播的视频帧率大多仍然处于20~30fps,已经无法满足用户对于高清、流畅的体验追求。而视频插帧算法,能够有效实现多倍率的帧率提升,有效消除低帧率视频的卡顿感,让视频变得丝滑流畅。配合其它的视频增强算法,更是能够让低质量视频焕然一新,让观众享受到极致的播放和观看体验。
      1039 0
      【OpenVI—视觉生产系列之视频插帧实战篇】几行代码,尽享流畅丝滑的视频观感