C 在 Oracle Blockchain Platform 上使用 EVM 运行 Solidity 智能合同
您可以在 Oracle Blockchain Platform 上以链代码方式部署以太坊虚拟机 (EVM) 来运行 Solidity 智能合约。
EVM 在以太坊网络中运行智能合约。EVM 是通过 Hyperledger Burrow 项目创建的,并集成到 Hyperledger Fabric 中。通过此项目,您可以使用 Hyperledger Fabric 许可的区块链平台与以 EVM 兼容语言(如 Solidity)编写的以太坊智能合约进行交互。请参见: Hyperledger Fabric EVM chaincode 。
- 将 EVM 链代码包上载到 Oracle Blockchain Platform 。
- 在通道上部署 EVM 链代码。
- 使用 Remix IDE 为 Solidity 智能合约生成字节码。
- 将智能合同字节码部署到部署的 EVM 链代码中。使用从部署返回的地址发送事务处理。
fabric-chaincode-evm:release-0.4
测试,可能无法与其他发行版一起使用。
设置 EVM 链代码程序包
必须先准备 EVM 链代码包,然后才能部署智能合同。要创建 chaincode 程序包文件夹:
- 从以下 GitHub 系统信息库下载 EVM 链代码软件包(
.zip
文件): Hyperledger Fabric EVM 链代码。 - 提取下载的文件
fabric-chaincode-evm-release-0.4.zip
。 - 在提取的文件中,导航到
fabric-chaincode-evm-release-0.4/evmcc
。 - 删除
go.sum
文件和vendor
目录。 - 使用
go mod
逗号作为所有相关 Go 模块的供应商:go mod tidy go mod vendor
- 导航到
fabric-chaincode-evm-release-0.4/emvcc/vendor/github.com/hyperledger
- 在
/hyperledger
目录中创建目录fabric-chaincode-evm/evmcc
。 - 将以下文件夹从
fabric-chaincode-evm-release-0.4/evmcc
目录移至fabric-chaincode-evm-release-0.4/evmcc/vendor/github.com/hyperledger/fabric-chaincode-evm/evmcc
目录:/address
/event
/eventmanager
/mocks
/statemanager
- 以
.zip
格式压缩顶层fabric-chaincode-evm-release-0.4/evmcc
文件夹并将其重命名。以下步骤使用evmcc.zip
作为示例名称。
在 Oracle Blockchain Platform 上部署 EVM 链代码
创建 EVM 链代码包后,可在 Oracle Blockchain Platform 上部署该包。
- 登录 Oracle Blockchain Platform 控制台。
- 在 Chaincodes 选项卡上,单击 Deploy a New Chaincode(部署新链代码)。
- 选择快速部署,然后输入以下信息:
- 程序包标签:输入链代码程序包的说明。
- Chaincode 语言:GoLang
- 链代码名称:输入链代码的名称。例如,输入
soliditycc
。 - 版本:
v1
- Init-required(需要初始化):将此保留为未选中状态。
- Channel:选择要安装链代码的渠道。
- Chaincode 源代码:上载您在前面的步骤中创建的
evmcc.zip
程序包。
提交信息后,EVM 链代码在 Chaincodes(链代码)选项卡中可见,并且在您选择安装它的每个通道上作为已部署链代码列出。
创建和编译 Solidity 智能合约
- 打开基于浏览器的 Remix IDE:https://remix.ethereum.org/ 。
- 如果您已经编写了 Solidity 智能合约,请将其导入到 Remix 中。
- 如果您没有编写 Solidity 智能合约,请在 Remix 中创建一个 Solidity 文件 (
.sol
),然后执行以下操作之一:- 如果您熟悉 Solidity,您可以创建自己的智能合约文件。
- 您可以使用 Solidity 文档中提供的 Simple Storage 示例代码: Solidity:Introduction to Smart Contracts
- 可以使用用于此示例的示例代码,该示例使用
string name
作为输入并使用set(name)
和get()
输出与输出字符串相同的代码:pragma solidity ^0.4.0; contract Myname { string public yourName; function set(string name) public { yourName = name; } function get() public view returns (string) { return yourName; } }
- 编译您的智能合约。在 Remix 中打开 Solidity Compiler 面板,确保打开智能合约选项卡以将其选择为正在编译的文件,将编译器版本设置为最新的 4。X 版本,然后单击“Compile(编译)”。
- 编译文件后,单击字节码图标以将字节码作为 JSON 文档复制到剪贴板。
- 将复制的字节码粘贴到文本编辑器中并保存它。
部署智能合同
"object"
字段。这是示例智能合同的 EVM 字节码。"object": "608060405234801561001057600080fd5b50610410806100206000396000f30060
8060405260043610610057576000357c0100000000000000000000000000000000000000000000000000000000900463
ffffffff1680634ed3885e1461005c5780636d4ce63c146100c5578063d97d663014610155575b600080fd5b34801561
006857600080fd5b506100c3600480360381019080803590602001908201803590602001908080601f01602080910402
602001604051908101604052809392919081815260200183838082843782019150505050505091929192905050506101
e5565b005b3480156100d157600080fd5b506100da6101ff565b60405180806020018281038252838181518152602001
91508051906020019080838360005b8381101561011a5780820151818401526020810190506100ff565b505050509050
90810190601f1680156101475780820380516001836020036101000a031916815260200191505b509250505060405180
910390f35b34801561016157600080fd5b5061016a6102a1565b60405180806020018281038252838181518152602001
91508051906020019080838360005b838110156101aa57808201518184015260208101905061018f565b505050509050
90810190601f1680156101d75780820380516001836020036101000a031916815260200191505b509250505060405180
910390f35b80600090805190602001906101fb92919061033f565b5050565b6060600080546001816001161561010002
03166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615
6101000203166002900480156102975780601f1061026c57610100808354040283529160200191610297565b82019190
6000526020600020905b81548152906001019060200180831161027a57829003601f168201915b505050505090509056
5b60008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190
818152602001828054600181600116156101000203166002900480156103375780601f1061030c576101008083540402
83529160200191610337565b820191906000526020600020905b81548152906001019060200180831161031a57829003
601f168201915b505050505081565b828054600181600116156101000203166002900490600052602060002090601f01
6020900481019282601f1061038057805160ff19168380011785556103ae565b828001600101855582156103ae579182
015b828111156103ad578251825591602001919060010190610392565b5b5090506103bb91906103bf565b5090565b61
03e191905b808211156103dd5760008160009055506001016103c5565b5090565b905600a165627a7a72305820a990d4
0b57c66329a32a18e847b3c18d6c911487ffadfed2098e71e8cafa0c980029",
to
地址。- 以太坊交易中必需的
input
。
要部署智能合同,to
字段是零地址,input
是合同的已编译 EVM 字节码。因此,为 invoke
命令提供了两个参数。第一个,传统上应该是链代码中的函数名称,现在是 0000000000000000000000000000000000000000
,第二个参数是 Solidity 智能合约字节码。
- 要在 Oracle Blockchain Platform 上部署 Solidity 智能合同,请使用 REST 代理端点使用这两个参数调用已部署的 EVM 链代码。
--data-raw '{"chaincode":"<chaincodename>","args":["<zeroaddress>","<EVMbytecode>"]}'
以下示例使用 cURL 将 Solidity 智能合同部署到名为soliditycc
的 Oracle Blockchain Platform 。curl -L -X POST 'https://<hostname>:443/restproxy/api/v2/channels/<channelname>/transactions' \ -H 'Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=' \ -H 'Content-Type: application/json' \ --data-raw '{"chaincode":"soliditycc","args":["0000000000000000000000000000000000000000","608060405234801561....152d2820d3b5d784b3711119691d0029"],"timeout":0,"sync":true}'
- 事务处理的响应
payload
是已部署合同的合同地址。复制此地址并保存它。运行智能合同功能时使用合同地址。
在此示例中,智能合同地址为66b92979bb66d645371b3247177e4b2513cb9834
。
与智能合约交互
拥有智能合同地址后,您可以使用以下调用通过 REST 代理与部署的智能合同进行交互。
要执行函数,可以使用调用和查询事务处理,但使用不同的参数。样例合同包含两个函数:get
和 set
。
在这些事务处理中,to
字段是合同地址,input
字段是与任何必需参数连接的函数执行散列。
您需要获取函数执行的散列才能运行事务处理。这样做的简单方法是执行 Remix IDE 中的函数,然后从事务日志中复制散列:
- 在 Remix IDE 中,打开 Deploy and Run Transactions(部署和运行事务处理)面板。确保在合同字段中选择了合同,然后单击部署。
部署完成后,合同将列在已部署合同列表中。 - 展开已部署合同列表中的合同。将列出智能合同功能。
- 运行事务处理。对于提供的示例,输入 oracle ,然后单击 set 。
- “终端”窗口显示事务处理日志。如果事务日志已最小化,则通过单击日志展开它们。通过单击
input
字段旁边的图标来复制该字段的值(即函数执行散列)。将此值保存到与合同地址相同的地点,并删除前导0x
。 - 在具有函数执行散列和合同地址后,可以使用散列和地址作为原始数据参数在 Oracle Blockchain Platform 上运行集事务处理。
例如,使用 cURL:--data-raw '{"chaincode":"<chaincodename>","args":["<contractaddress>","<setfunctionexecutionhash>"]}'
curl -L -X POST 'https://<hostname>:443/restproxy/api/v2/channels/<channelname>/transactions' \ -H 'Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=' \ -H 'Content-Type: application/json' \ --data-raw '{"chaincode":"soliditycc","args":["66b92979bb66d645371b3247177e4b2513cb9834","4ed3885e000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000066f7261636c650000000000000000000000000000000000000000000000000000"]}'
- 打开 Oracle Blockchain Platform 控制台,检查事务处理是否列在分类账中。
要使用智能合同的 get
函数运行其他事务处理,例如查询,您可以在 Remix 中生成函数执行散列,然后将其与合同地址合并:
- 在部署和运行事务处理面板上的“重组”中,确保您的合同仍列在部署的合同下。如果没有,则重新部署。
- 单击 get 。与使用 set 事务时一样,从事务中检索并保存输入,同时删除前导
0x
。 - 您可以使用此事务处理散列和合同地址针对 Oracle Blockchain Platform 上部署的链代码运行查询事务处理。
例如,在 cURL 中:--data-raw '{"chaincode":"<chaincodename>","args":["<contractaddress>","<getfunctionexecutionhash>"]}'
返回的有效负载将包含要查询的资产 - 在本例中,字符串为curl -L -X POST 'https://<hostname>:443/restproxy/api/v2/channels/<channelname>/chaincode-queries' \ -H 'Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=' \ -H 'Content-Type: application/json' \ --data-raw '{"chaincode":"soliditycc","args":["66b92979bb66d645371b3247177e4b2513cb9834","6d4ce63c"]}'
oracle
。