Ethereum生态的不断壮大,导致交易数量急剧增加,用户不得不在交易速度和手续费之间做出艰难的选择。随着DeFi和NFT项目持续火爆,产生了高额利润催生了大量的“套利”交易,导致用户对区块链数据隐私的需求不断增加。PlatON结合区块链、人工智能和隐私计算技术,建立了一个去中心化的协作式隐私人工智能区块链网络。相较于以太坊在交易速度、交易成本和数据隐私方面有巨大的优势。为提高开发效率,PlatON 1.1.1版本和Alaya0.16.1版本将开始全面兼容Ethereum生态工具。本文将以ENS为例,讲解如何将Ethereum智能合约迁移到PlatON中。

ENS(Ethereum Name Service)是一个基于Ethereum的分布式、开放和可扩展的命名系统。ENS是一个层次结构的域名系统,层次的名称叫做域,不同域之间以“点“作为分隔符,一个域的所有者能够完全控制其子域。ENS主要由注册表和解析器组成。其中,注册表用于维护所有域名和子域名列表,解析器负责将域名转换为地址。通过分析ENS智能合约,ENSRegistry.sol合约实现了注册表功能;ensdomains/resolver/PublicResolver合约实现了解析器功能。为实现子域名自动化注册,需要部署FIFSRegistrar.sol合约。此外,启用ENS反向解析,需部署ReverseRegistrar.sol合约。

在Ethereum生态中,用于智能合约部署的工具主要有Truffle和Remix两种,首先介绍如何使用Truffle部署合约。

一、使用Truffle迁移ENS合约

1.1安装Truffle

首先需要利用高于v8.9.4的nodejs安装Truffle

npm install -g truffle

Truffle使用文档

1.2 下载编译ENS合约

Step1 下载ENS合约

git clone https://github.com/ensdomains/ens.git && cd ens

Step2 使用truffle初始化一个工程

truffle init

在操作完成之后,就有如下项目结构:

  • contracts/: Solidity合约目录
  • migrations/: 部署脚本文件目录
  • test/: 测试脚本目录
  • truffle-config.js: platon-truffle 配置文件
    Step3 修改platon-truffle 配置文件truffle-config.js
    PlatON测试网RPC信息:
  • chainid为210309
  • RPC为http://35.247.155.162:6789、"https://devnetopenapi.platon.network/rpc" 以及 ws://35.247.155.162:6790
    前往PlatON测试网水龙头,在水龙头中输入的地址可以是LAT或0x格式的地址.
vim truffle-config.js

truffle-config.js 修改部分内容如下:

development: {host: "35.247.155.162",     // RPC(default: none)port: 6789,            // Standard PlatON port (default: none)network_id: "*",       // Any network (default: none)from: "地址",        // Account to send txs from (default: accounts[0]) 这个地址格式可以是0x或LAT,建议使用0x格式
},...compilers: {solc: {version: "^0.5.17",    // 此版本号与合约声明的版本号保持一致}
}

Step4 编译合约

truffle compile

在操作完成之后,生成如下目录结构:

  • build/: Solidity合约编译后的目录
  • build/contracts/: 对应的编译文件

1.3 部署ENS合约

Step1 新增合约部署脚本文件

cd migrations/ && vim 2_initial_ens.js

部署脚本文件名建议使用合约名称便于后面维护,如ENS合约对应的部署脚本文件为2_initial_ens.js,内容如下所示:

const ENS = artifacts.require("@ensdomains/ens/ENSRegistry");
const FIFSRegistrar = artifacts.require("@ensdomains/ens/FIFSRegistrar");
const ReverseRegistrar = artifacts.require("@ensdomains/ens/ReverseRegistrar");
const PublicResolver = artifacts.require("@ensdomains/resolver/PublicResolver");const utils = require('web3-utils');
const namehash = require('eth-ens-namehash');const tld = "test";module.exports = function(deployer, network, accounts) {let ens;let resolver;let registrar;// Registrydeployer.deploy(ENS)// Resolver.then(function(ensInstance) {ens = ensInstance;return deployer.deploy(PublicResolver, ens.address);}).then(function(resolverInstance) {resolver = resolverInstance;return setupResolver(ens, resolver, accounts);})// Registrar.then(function() {return deployer.deploy(FIFSRegistrar, ens.address, namehash.hash(tld));}).then(function(registrarInstance) {registrar = registrarInstance;return setupRegistrar(ens, registrar);})// Reverse Registrar.then(function() {return deployer.deploy(ReverseRegistrar, ens.address, resolver.address);}).then(function(reverseRegistrarInstance) {return setupReverseRegistrar(ens, resolver, reverseRegistrarInstance, accounts);})
};async function setupResolver(ens, resolver, accounts) {const resolverNode = namehash.hash("resolver");const resolverLabel = utils.sha3("resolver");await ens.setSubnodeOwner("0x0000000000000000000000000000000000000000", resolverLabel, accounts[0]);await ens.setResolver(resolverNode, resolver.address);await resolver.setAddr(resolverNode, resolver.address);
}async function setupRegistrar(ens, registrar) {await ens.setSubnodeOwner("0x0000000000000000000000000000000000000000", utils.sha3(tld), registrar.address);
}async function setupReverseRegistrar(ens, resolver, reverseRegistrar, accounts) {await ens.setSubnodeOwner("0x0000000000000000000000000000000000000000", utils.sha3("reverse"), accounts[0]);await ens.setSubnodeOwner(namehash.hash("reverse"), utils.sha3("addr"), reverseRegistrar.address);
}

Step2 解锁账户
进入Truffle控制台

truffle console

导入账户

web3.eth.personal.importRawKey('私钥','密码')    // 私钥没有0x前缀

解锁账户

web3.eth.personal.unlockAccount('地址', '密码', 999999)

Step3 合约部署

truffle migrate

当看到以下内容代表合约已经部署成功。Gas实际上使用LAT结算,因此用于部署合约的地址中需要有一定的LAT。

Replacing 'ENSRegistry'-----------------------> transaction hash:    0x7f166ce0d1287202e0583c739cacb77d0166fb8c5c459b9aecd2491e44bfc5ba> Blocks: 4            Seconds: 4> contract address:    0x5215c9F58E1Bf2c4BF6c7B5F80AD612CE0623AA9> block number:        6157441> block timestamp:     1637306960253> account:             0x54AFd12E9e5678F3Fc6f528120e1a13cb9c3c2AF> balance:             198.00101596> gas used:            584642 (0x8ebc2)> gas price:           500 gwei> value sent:          0 ETH> total cost:          0.292321 ETHReplacing 'PublicResolver'--------------------------> transaction hash:    0x78b33dc7ca8df8f72c0da17fd8d125207bc7903039c2987578500a150e32499d> Blocks: 2            Seconds: 4> contract address:    0xA447FDd6c8BF9Ce3Ce80f52b7075d5651D301369> block number:        6157448> block timestamp:     1637306967968> account:             0x54AFd12E9e5678F3Fc6f528120e1a13cb9c3c2AF> balance:             196.30776246> gas used:            3386507 (0x33ac8b)> gas price:           500 gwei> value sent:          0 ETH> total cost:          1.6932535 ETHReplacing 'FIFSRegistrar'-------------------------> transaction hash:    0xcc61e6a21a9ec5b1f4678becbde438846396fbee59616f58898d05d5c8faa9e8> Blocks: 2            Seconds: 4> contract address:    0xd72eF5Af584bc13799361505207B3508bc317D93> block number:        6157470> block timestamp:     1637306992188> account:             0x54AFd12E9e5678F3Fc6f528120e1a13cb9c3c2AF> balance:             196.13476646> gas used:            202670 (0x317ae)> gas price:           500 gwei> value sent:          0 ETH> total cost:          0.101335 ETHReplacing 'ReverseRegistrar'----------------------------> transaction hash:    0x80a6bb520f60849a385691e84600518a98308bd6e1cc2ecfbca66d79a1c36b3b> Blocks: 3            Seconds: 4> contract address:    0x7431eB4F2f8B55c76017b8e26fc0B7205709F08F> block number:        6157481> block timestamp:     1637307004348> account:             0x54AFd12E9e5678F3Fc6f528120e1a13cb9c3c2AF> balance:             195.85967096> gas used:            505078 (0x7b4f6)> gas price:           500 gwei> value sent:          0 ETH> total cost:          0.252539 ETH> Saving artifacts-------------------------------------> Total cost:           2.3394485 ETHSummary
=======
> Total deployments:   4
> Final cost:          2.3394485 ETH

二、使用Remix迁移ENS合约

使用Truffle迁移智能合约并非是最佳选择,主要原因包括三点:一是,需部署额外的Migrations.sol合约,增加了部署成本;二是,若部署合约所需时间较长,无法及时根据网络拥堵情况,灵活调整Gas;三是,部署过程中需全程保证网络链接,一旦失去网络链接需从头开始部署合约。而使用Remix可以较好的解决上述问题。

2.1 将合约导入Remix

通过分析可知,迁移ENS需要部署四个智能合约。这四个合约分别位于https://github.com/ensdomains/ens/tree/master/contractshttps://github.com/ensdomains/resolvers内。首先进入https://remix.ethereum.org/将所有合约导入Remix中,如图1所示。

图1 ENS所涉及到的合约

2.2 部署合约

根据合约依赖关系,需要第一个部署的是注册表合约,即ENSRegistry.sol。首先,选择所需部署的合约;其次,根据合约声明选择solidity版本;最后,点击Compile ContractName编译合约,如图2、3所示。

图2 选择所需部署的合约 图3 编译所需部署的合约

若编译成功,则进入Remix的部署界面,完成ENSRegistry合约的部署,如图4所示。部署时,首先将PlatON测试网RPC添加到MateMask中,通过私钥将LAT地址导入到MateMask中;其次,在Remix的deploy界面中将ENVIRONMENT设置为Injected Web3 ,并将CONTRACT设置为所需部署的合约;然后,点击Deploy可以设置该笔交易的Gas Price,如图5所示;最后,在MateMask中点击确认,便成功部署该合约。

图4 合约部署界面 图5 调整交易Gas Price价格

同理,使用Remix部署其余三个合约与部署ENSRegistry.sol方法一致。需额外注意的有三点。一是,如果合约通过import "@PATH/contractName.sol"导入其他合约,需要统一修改为import "https://github.com/PATH/contractName.sol";二是,若导入合约所使用solidity版本与项目版本不一致,需修改solidity版本和因此导致的编译错误;三是,构造函数需要传参时,需在Deploy后面传入参数。入参大于一时,使用“,”分割,如图6所示。

图6 构造函数传参 ## 三、合约测试

如果使用Truffle部署合约,可以使用Web3对部署的合约进行调试。首先,通过npm install web3安装web3包。由于项目需要调试的内容比较多,本文只介绍测试程序的主要框架。

const Web3 = require('web3')
const HttpProvider = ${RPC}
const web3 = new Web3(new Web3.providers.HttpProvider(HttpProvider))const fs = require("fs");
const ABIString= fs.readFileSync("./build/contracts/fileName.json", "utf-8");
const ABIJSON= JSON.parse(ABIString);const privateKey = '私钥'
web3.eth.accounts.wallet.add(privateKey)
const myAddr = web3.eth.accounts.wallet[0].address
var ContractName = new web3.eth.Contract(ABIJSON.abi,'ContractAddr');async function test() {// 修改合约状态的方法var renturnsContent = await ContractName.methods.methodsName(param).send({from:myAddr,gas:2000000,gasPrice:"999999"},function(error,txHash){console.log("error:",error);console.log("txHash:",txHash);})console.log("renturnsContent:",renturnsContent);// 查询合约状态var renturnsContent= await ContractName.methods.methodsName(param).call()console.log("renturnsContent:",renturnsContent);
}

如果使用Remix部署合约,合约部署成功之后在Deployed Contract下面会显示合约名称,合约地址和合约的对外方法,如图7所示。

图7 Remix合约调试界面

至此,将ENS迁移到PlatON的整个流程介绍完毕。整个流程与在Ethereum上部署合约的体验一致,说明PlatON在兼容Ethereum生态方面已经足够成熟,将一步降低了Ethereum开发者在PlatON上的开发成本。期待,PlatON借助自身的隐私计算、AI方面的优势以及Ethereum强悍的生态,打造一更加强悍的生态,更好的服务于实体经济的发展。

Ethereum智能合约迁移到PlatON教程相关推荐

  1. 教程 | 以太坊智能合约编程之菜鸟教程

    教程 | 以太坊智能合约编程之菜鸟教程 译注:原文首发于ConsenSys开发者博客,原作者为Eva以及ConsenSys的开发团队.如果您想要获取更多及时信息,可以访问ConsenSys首页点击左下 ...

  2. 以太坊智能合约编程之菜鸟教程

    手把手带你走上智能合约编程之路 译注:原文首发于ConsenSys开发者博客,原作者为Eva以及ConsenSys的开发团队.如果您想要获取更多及时信息,可以访问ConsenSys首页点击左下角New ...

  3. ETH智能合约开发手把手入门教程|猿创征文

    文章目录 安装钱包 安装 Metamask.并创建好账号 执行第一次转账 测试币获取 第一次转账 第一个智能合约 使用 Remix 创建第一个合约 使用 Remix 测试第一个合约 使用 Remix ...

  4. 以太坊(Ethereum) - 什么是智能合约

    章节 以太坊(Ethereum) – 是什么 以太坊(Ethereum) – 什么是智能合约 以太坊(Ethereum) – 以太币 以太坊(Ethereum) – 虚拟机(E.V.M.) 以太坊(E ...

  5. 四十种 智能合约 支持平台

    目录 1. 以太坊( Ethereum ) 2. Quorum 3. Wanchain 4. æternity 5. Zen 6. Counterparty 7. Rootstock (RSK) 8. ...

  6. 以太坊智能合约之如何执行智能合约?

    区块链技术在顶级技术中占据主导地位的主要原因在于其去中心化.虽然区块链的主要目的是在没有中心的情况下维护交易记录,但为了实现自动化,智能合约被引入.那么在写完智能合约之后呢?在本文的这个以太坊智能合约 ...

  7. 数字商品指南系列第三篇:编写智能合约并编译部署

    文章目录 前言 警告 完善项目结构 编写合约代码 编译合约 部署合约 总结 捐赠渠道 前言 智能合约为数字藏品提供技术支持,它可以定义数字藏品的简称.全称.发行数量.铸造方法.版权税等等,所有关于数字 ...

  8. 以太坊智能合约开发-《精通以太坊智能合约开发》学习总结实践

    文章目录 一.初探以太访智能合约 1. remix小demo 2. 写智能合约用的编程语言 二.以太坊核心概念 1. 交易/事务( Transaction ) 2. 区块 3. 共识协议:工作量证明( ...

  9. 使用Remix编译和部署以太坊智能合约

    链客,专为开发者而生,有问必答! 此文章来自链客区块链技术问答社区,未经允许拒绝转载. 使用Remix编译和部署以太坊智能合约 Remix 是一个开源的 Solidity 智能合约开发环境,提供基本的 ...

最新文章

  1. 一篇文章教会你利用Python网络爬虫获取Mikan动漫资源
  2. python函数教程:global 和 nonlocal的详细用法
  3. CCNP学习笔记7-路由部分--OSPF综合题2
  4. 作者:廖小飞,博士,华中科技大学计算机科学与技术学院教授、博士生导师。...
  5. 基础编程题目集 6-1 简单输出整数 (10 分)
  6. python导入模块的常用方法_(9)python模块的定义、导入、优化,常用模块
  7. html文件怎么兼容浏览器,如何扫描HTML和跨浏览器兼容的JavaScript文件?
  8. 萤火虫小程序_新款预览 | 原创森林系列 冰川上 / 小程序改版啦。
  9. spss常态检验_利用SPSS检验数据是否符合正态
  10. mysql dump hbase_导入mysqldump表结构
  11. 软件设计师2018上半年+历年资料
  12. FFMPEG详细参数
  13. 蓝桥杯 java 跳马问题
  14. 魅族mx4 android5.0,第一手更新 魅族MX4Pro安卓5.0抢先体验
  15. 【C语言-09】给定两个整形变量的值,将两个值的内容进行交换。(内附异或法原理讲解哦~)
  16. TSE for SketchUp Pro - 建筑行业
  17. 关于 Kubernetes集群中仪表盘(dashboardKuboard)安装的一些笔记
  18. 《面朝大海,春暖花开》——海子
  19. 使用FTP删不掉文件的解决方法
  20. 二级c语言编译完程序如何运行,计算机二级C语言辅导:C++环境下编译和运行c语言...

热门文章

  1. 第47章 QR-Decoder-OV5640二维码识别—零死角玩转STM32-F429系列
  2. 百度地图JavaScript API 学习之地址解析
  3. java 排队_实验排队功能实现(JAVA)
  4. [入门教程](python numpy入门)
  5. 【reID学习记录】Person_reID_baseline_pytorch学习
  6. STM32_RTC晶振不起振的原因及解决方法
  7. [转]个性化推荐--能否造就下一代霸主?
  8. 2016年的不正式总结
  9. sybase数据库中时间类型转换以及比较
  10. c语言1017错误什么意思,错误 C1017