Microsoft Enclave EVM (Ethereum EVM + Intel SGX)项目运行测试 (Windows 10)

@(Blockchain)[Win10|Ethereum|SGX]

微软在Github发布了一个Ethereum和Intel SGX结合的项目Enclave EVM(eEVM)

本文记录了在Win10 环境下运行测试遇到的一些问题和解决方法。

如果不想了解过多错误纠正过程,可以直接看Step 5、6、8


Enclave EVM 介绍

Enclave EVM (eEVM) 是一个开源的、独立的、可嵌入的、c++实现的Ethereum虚拟机。它最初是构建在open enclave SDK之上的可信执行环境TEE(i.e, SGX enclave)内运行的,以便与微软的Confidential Consortium Framework一起使用。

Enclave EVM (eEVM) is an open-source, standalone, embeddable, C++ implementation of the Ethereum Virtual Machine. It was originally built to run within a TEE (ie, SGX enclave) on top of the Open Enclave SDK, for use with Microsoft's Confidential Consortium Framework.

运行环境

  • 系统:Windows 10 教育版 64位

  • IDE:Visual Studio 2017 Professional

    SGX编译按官方说明要求是:Visual Studio 2015/2017

  • 依赖项:CMake. Minimum version 3.10.

    一般VS自带的就可以了, 必须x64编译

  • Solidity:https://github.com/ethereum/solidity/releases

    之前学习以太坊的过程一般都是已经安装了solc编译器的
    npm install -g solc
    不过这种安装方法在本项目运行中会遇到问题,后面会具体说明

接下来就是整个项目的运行测试过程:

Step 1: 下载Enclave EVM(eEVM)项目

下载地址:https://github.com/microsoft/eEVM
直接下载压缩包,找个某个目录解压缩,我选择E:,那么解压后目录为:E:\eEVM

1 下载解压.PNG

Step 2:编译eEVM

根据eEVM项目说明:
打开Visual Studio 2017 developer command prompt (VS2017的开发人员命令提示符)。创建.sln和.vcxproj文件,并按如下方式构建静态库和测试。

  1. 进入eEVM目录,创建build文件夹。
**********************************************************************
** Visual Studio 2017 Developer Command Prompt v15.9.17
** Copyright (c) 2017 Microsoft Corporation
**********************************************************************

D:\Program Files (x86)\Microsoft Visual Studio\2017\Professional>E:
E:\>cd eEVM
E:\eEVM>mkdir build
  1. 进入build文件夹,编译整个项目。
E:\eEVM>cd build
E:\eEVM\build>cmake ..
-- Building for: Visual Studio 15 2017
-- The C compiler identification is MSVC 19.16.27034.0
-- The CXX compiler identification is MSVC 19.16.27034.0
-- Check for working C compiler: D:/Program Files (x86)/Microsoft Visual Studio/2017/Professional/VC/Tools/MSVC/14.16.27023/bin/Hostx86/x86/cl.exe
-- Check for working C compiler: D:/Program Files (x86)/Microsoft Visual Studio/2017/Professional/VC/Tools/MSVC/14.16.27023/bin/Hostx86/x86/cl.exe -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: D:/Program Files (x86)/Microsoft Visual Studio/2017/Professional/VC/Tools/MSVC/14.16.27023/bin/Hostx86/x86/cl.exe
-- Check for working CXX compiler: D:/Program Files (x86)/Microsoft Visual Studio/2017/Professional/VC/Tools/MSVC/14.16.27023/bin/Hostx86/x86/cl.exe -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: E:/eEVM/build

build文件夹目录如下:

2 编译.PNG

编译成功,从x86/cl.exe可以看到VS是用32位编译的。

实际上,用32位编译会导致后续项目生成错误,如果不想了解错误原因可以直接跳到Step4:重新编译eEVM

Step 3:生成eEVM项目

创建生成项目debug

E:\eEVM>msbuild ALL_BUILD.vcxproj

报错:

“E:\eEVM\build\ALL_BUILD.vcxproj”(默认目标) (1) ->
“E:\eEVM\build\disassembler.vcxproj”(默认目标) (3) ->
“E:\eEVM\build\eevm.vcxproj”(默认目标) (4) ->
(ClCompile 目标) ->
  E:\eEVM\3rdparty\intx\include\intx/int128.hpp(298): error C3861: “_umul128”: 找不到标识符 [E:\eEVM\build\eevm.vcxproj]
  E:\eEVM\3rdparty\intx\include\intx/int128.hpp(298): error C3861: “_umul128”: 找不到标识符 [E:\eEVM\build\eevm.vcxproj]
  E:\eEVM\3rdparty\intx\include\intx/int128.hpp(298): error C3861: “_umul128”: 找不到标识符 [E:\eEVM\build\eevm.vcxproj]
  E:\eEVM\3rdparty\intx\include\intx/int128.hpp(298): error C3861: “_umul128”: 找不到标识符 [E:\eEVM\build\eevm.vcxproj]
  E:\eEVM\3rdparty\intx\include\intx/int128.hpp(298): error C3861: “_umul128”: 找不到标识符 [E:\eEVM\build\eevm.vcxproj]
  E:\eEVM\3rdparty\intx\include\intx/int128.hpp(298): error C3861: “_umul128”: 找不到标识符 [E:\eEVM\build\eevm.vcxproj]
  
    19 个警告
    6 个错误

查阅了很多资料是因为VS cmake默认使用x86 32位编译,这个错误必须使用x64 64位编译才可以。因此我们编译的时候需要指定x64编译。

Step 4:重新编译eEVM

首先删除build目录下的所有文件,重新按照以下命令编译:

E:\eEVM>cd build
E:\eEVM\build>cmake -G "Visual Studio 15 Win64" ..
-- The C compiler identification is MSVC 19.16.27034.0
-- The CXX compiler identification is MSVC 19.16.27034.0
-- Check for working C compiler: D:/Program Files (x86)/Microsoft Visual Studio/2017/Professional/VC/Tools/MSVC/14.16.27023/bin/Hostx86/x64/cl.exe
-- Check for working C compiler: D:/Program Files (x86)/Microsoft Visual Studio/2017/Professional/VC/Tools/MSVC/14.16.27023/bin/Hostx86/x64/cl.exe -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: D:/Program Files (x86)/Microsoft Visual Studio/2017/Professional/VC/Tools/MSVC/14.16.27023/bin/Hostx86/x64/cl.exe
-- Check for working CXX compiler: D:/Program Files (x86)/Microsoft Visual Studio/2017/Professional/VC/Tools/MSVC/14.16.27023/bin/Hostx86/x64/cl.exe -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: E:/eEVM/build

编译成功,从x64/cl.exe可以看到VS是用64位编译的。生成的build目录相同。

Step 5:重新生成eEVM项目

用相同的命令:

E:\eEVM>msbuild ALL_BUILD.vcxproj

可能遇到的错误:

“E:\eEVM\build\ALL_BUILD.vcxproj”(默认目标) (1) ->
“E:\eEVM\build\eevm_tests.vcxproj”(默认目标) (5) ->
(ClCompile 目标) ->
  E:\eEVM\tests\rlp.cpp(215): error C2398: 元素“4”: 从“int”转换到“_Ty”需要收缩转换 [E:\eEVM\build\eevm_tests.vcxproj]
  E:\eEVM\tests\rlp.cpp(216): error C2398: 元素“5”: 从“int”转换到“_Ty”需要收缩转换 [E:\eEVM\build\eevm_tests.vcxproj]
  E:\eEVM\tests\rlp.cpp(215): error C2398: 元素“4”: 从“int”转换到“_Ty”需要收缩转换 [E:\eEVM\build\eevm_tests.vcxproj]
  E:\eEVM\tests\rlp.cpp(216): error C2398: 元素“5”: 从“int”转换到“_Ty”需要收缩转换 [E:\eEVM\build\eevm_tests.vcxproj]

    53 个警告
    4 个错误

这个看起来是一个类型转换的错误:

E:\eEVM\tests\rlp.cpp(216): error C2398: 元素“5”: 从“int”转换到“_Ty”需要收缩转换 [E:\eEVM\build\eevm_tests.vcxproj]
          with
          [
              _Ty=uint8_t
          ]
E:\eEVM\tests\rlp.cpp(215): error C2398: 元素“4”: 从“int”转换到“_Ty”需要收缩转换 [E:\eEVM\build\eevm_tests.vcxproj]
          with
          [
              _Ty=uint16_t
          ]

实际错误的位置是在TEST_CASE_TEMPLATE中(205-216行):

3 类型错误.PNG

我自己是直接打开E:\eEVM\tests中的rlp.cpp文件,把类型修改直接扩大。
uint8_6uint16_t都改成uint64_t

4 修改类型.PNG

保存修改结果。

Step 6:再次重新编译生成eEVM项目

以防万一,还是全部删除build中的文件,重新编译,再重新生成。

E:\eEVM\build>cmake -G "Visual Studio 15 Win64" ..
E:\eEVM\build>msbuild ALL_BUILD.vcxproj

eEVM项目生成成功,警告可以忽略:

FinalizeBuildStatus:
  正在删除文件“sum.dir\Debug\sum.tlog\unsuccessfulbuild”。
  正在对“sum.dir\Debug\sum.tlog\sum.lastbuildstate”执行 Touch 任务。
已完成生成项目“E:\eEVM\build\sum.vcxproj”(默认目标)的操作。

PrepareForBuild:
  正在创建目录“x64\Debug\ALL_BUILD\”。
  正在创建目录“x64\Debug\ALL_BUILD\ALL_BUILD.tlog\”。
InitializeBuildStatus:
  正在创建“x64\Debug\ALL_BUILD\ALL_BUILD.tlog\unsuccessfulbuild”,因为已指定“AlwaysCreate”。
CustomBuild:
  Building Custom Rule E:/eEVM/CMakeLists.txt
FinalizeBuildStatus:
  正在删除文件“x64\Debug\ALL_BUILD\ALL_BUILD.tlog\unsuccessfulbuild”。
  正在对“x64\Debug\ALL_BUILD\ALL_BUILD.tlog\ALL_BUILD.lastbuildstate”执行 Touch 任务。
已完成生成项目“E:\eEVM\build\ALL_BUILD.vcxproj”(默认目标)的操作。


已成功生成。

...

    56 个警告
    0 个错误

整个项目生成成功后,build文件夹目录下多出了一些文件:

5 生成成功.PNG

Step 7:运行测试(可选)

build中使用命令:

ctest -C debug

报错:

E:\eEVM\build>ctest -C debug
Test project E:/eEVM/build
    Start 1: eevm_tests
Process not started
 E:/eEVM/tests/unit_test_wrapper.sh
[unknown error]
1/1 Test #1: eevm_tests .......................***Not Run   0.00 sec

0% tests passed, 1 tests failed out of 1

Total Test time (real) =   0.02 sec

The following tests FAILED:
          1 - eevm_tests (BAD_COMMAND)
Errors while running CTest

应该是E:/eEVM/tests目录下脚本文件unit_test_wrapper.sh参数错误。我查询了一些资料,由于不是很了解,不过没有找出解决方法,有兴趣的可以尝试修改。因为不影响其他测试,我就没有管它了。

也就是Step 7可以忽略不管。

Step 8:3个实例运行测试(必选)

我们可以看到E:\eEVM\samples下有几个例子,我选择hello_worldsumerc20三个例子分别说明。

它们都是在Intel SGX中运行的。

对于这三个例子,在项目生成成功后也分别生成了debug文件。在E:\eEVM\build\Debug中,我们可以看到hello_world.exesum.exeerc20.exe

进入E:\eEVM\build\Debug文件夹,打开cmd

1. hello_world测试(打印Hello world!)

输入命令:

hello_world.exe

运行成功,屏幕打印Hello world!

E:\eEVM\build\Debug>hello_world.exe
Hello world!

2. sum测试(两数求和)

输入命令:

sum.exe 2 3

运行成功,这里都是16进制:

E:\eEVM\build\Debug>sum.exe 2 3
0x2 + 0x3 = 0x5
E:\eEVM\build\Debug>sum 10 12
0xa + 0xc = 0x16

3. erc20测试(智能合约转账)

E:\eEVM\samples\erc20文件夹下有三个文件:

  • ERC20.sol:Solidity编写的智能合约源代码
  • ERC20_combined.json:Solidity编译(solc)ERC20.sol生成的json文件
  • main.cpp:读取合约,在SGX中运行合约的main文件

输入命令:

erc20 E:\eEVM\samples\erc20\ERC20_combined.json

运行成功:

E:\eEVM\build\Debug>erc20 E:\eEVM\samples\erc20\ERC20_combined.json
-- Initial state --
Total supply of tokens is: 0x3e8
User balances:
 0x3e8 owned by 0xEcaED682C12Ab04F8D740Cce950B7C1A1C75837b (original contract creator)
 0x0 owned by 0xD8dEA72EA703C7647F4Eaf8CA342Ead51D1AD7EF
-------------------

Transferring 0x14d from 0xEcaED682C12Ab04F8D740Cce950B7C1A1C75837b to 0xD8dEA72EA703C7647F4Eaf8CA342Ead51D1AD7EF
 (succeeded)
Transferring 0x14e from 0xD8dEA72EA703C7647F4Eaf8CA342Ead51D1AD7EF to 0xEcaED682C12Ab04F8D740Cce950B7C1A1C75837b
 (failed)

-- After one transaction --
Total supply of tokens is: 0x3e8
User balances:
 0x29b owned by 0xEcaED682C12Ab04F8D740Cce950B7C1A1C75837b (original contract creator)
 0x14d owned by 0xD8dEA72EA703C7647F4Eaf8CA342Ead51D1AD7EF
---------------------------

Transferring 0x9 from 0xEcaED682C12Ab04F8D740Cce950B7C1A1C75837b to 0x5692079Fa1291630F173cA9C5494C9C2bd07AbA7
 (succeeded)
...
Transferring 0x43 from 0xE3367872f7fd5E4Ff0A5eD4A412551B293D29D19 to 0x3Ae16AC485c4B0687D7516008B018c972460348D
 (failed)

-- Final state --
Total supply of tokens is: 0x3e8
User balances:
 0x2cd owned by 0xEcaED682C12Ab04F8D740Cce950B7C1A1C75837b (original contract creator)
 0xb4 owned by 0xD8dEA72EA703C7647F4Eaf8CA342Ead51D1AD7EF
 0x9 owned by 0x5692079Fa1291630F173cA9C5494C9C2bd07AbA7
 0x5 owned by 0x3Ae16AC485c4B0687D7516008B018c972460348D
 0x8 owned by 0x3116BE2D5765CA64e65c375E728d67CA7bC8F5A5
 0x51 owned by 0x2AF018a4A69Cf4aEEeD5579e19A82B828B351c29
 0x0 owned by 0x922674d873402Fc975F80e597FE657852d8d947C
 0x0 owned by 0xE3367872f7fd5E4Ff0A5eD4A412551B293D29D19
-----------------

补充:如何编译自己的合约?

我们可以看到ERC20.sol必须要有对应的ERC20_combined.json,才能运行。但是.json文件时如何得到的呢?

我们可以用Solidity自带的solc命令编译.sol文件生成对应的.json文件。

(1)首先安装solc

因为之前有过以太坊的学习,其实都安装过了。命令如下:

npm install -g solc

(2)查看solc是否安装成功。

$ solcjs --version
0.6.0+commit.26b70077.Emscripten.clang

Windows下solc --versionsolc --help都会报错,自然所有solc命令都会报错。原因看Solodity文档。

(3)安装Windows Solidity Release版本的solc

地址:https://github.com/ethereum/solidity/releases

可以自己选择对应版本,下载解压到某个选定的目录。
把所在目录如D:\Program Files (x86)\Solidity加入环境变量。我把用户变量和系统变量的Path中都加入了D:\Program Files (x86)\Solidity
具体方法:系统->高级系统设置->环境变量->(用户变量/系统变量)->Path->新建。

这时候使用solc命令可以看到安装成功:

C:\Users\A>solc --version
solc, the solidity compiler commandline interface
Version: 0.6.0+commit.26b70077.Windows.msvc

注意:
其实我最开始这样安装完,solc命令还是报错,不知道第二天为什么就好了。

如果还是无法使用solc命令,可以把需要编译的.sol文件放到刚刚安装solc的目录下,也就是D:\Program Files (x86)\Solidity中,在这个文件夹中,直接使用solc --versionsolc --help是没有问题的,其他的solc命令也同样可以使用。

(4)编译.sol文件。

随意选择某个位置,创建一个新文件夹,将ERC20.sol复制进去。在该文件夹中,打开cmd使用如下命令:

solc --evm-version homestead --combined-json bin,hashes --pretty-json --optimize ERC20.sol > ERC20_combined.json

可以看到生成了ERC20_combined.json

为了对比编译结果,我实际上安装了solc 0.6.0solc 0.4.24两个版本。不过系统变量添加的是solc 0.6.0

因为Solidity更新较快,不同版本编译器的语法要求变化也较大,很多低版本的语法在高版本已无法编译通过。eEVM使用的是solc 0.4.24.sol合约中其实也会指明编译器的版本,必须要与使用的编译器版本匹配才不会报错,不然就会出现错误:

F:\compile_test>solc --evm-version homestead --combined-json bin,hashes --pretty-json --optimize ERC20.sol > ERC20_combined.json
Error: Source file requires different compiler version (current compiler is 0.6.0+commit.26b70077.Windows.msvc - note that nightly builds are considered to be strictly less than the released version
 --> ERC20.sol:1:1:
  |
1 | pragma solidity ^0.4.0;
  | ^^^^

根据报错修改ERC20.sol文件,有些语法也需要修改。例如:

  • constant关键字已被删除,需要使用view/pure
    重新编译即可:
    6 高版本json.PNG

对比原始项目中的ERC20_combined.json文件:

7 原始json.PNG

如果你想用solc 0.4.24编译,就把文件放到solc 0.4.24目录下,且不需要修改语法,在该目录下打开cmd编译:

D:\Program Files\Solidity>solc --evm-version homestead --combined-json bin,hashes --pretty-json --optimize ERC20.sol > ERC20_combined.json

D:\Program Files\Solidity>solc --version
solc, the solidity compiler commandline interface
Version: 0.4.24+commit.6ae8fb59.Windows.msvc

得到的json文件对比,和项目中的原始文件一模一样。

我也用solc 0.4.24编译了之前以太坊公开拍卖智能合约(truffle + ganache-cli)文章中学习的SimpleAuction.sol。编译成功:

8 sol测试.PNG

不过我暂时还没有为SimpleAuction.sol合约写它的main.cpp运行测试文件,所以没有放在整个项目中测试。

自定义合约的测试在后续学习中会进行。


本文作者:Joyce
文章来源:https://www.jianshu.com/p/d5ba22d7d655
版权声明:转载请注明出处!

你可能感兴趣的:(Microsoft Enclave EVM (Ethereum EVM + Intel SGX)项目运行测试 (Windows 10))