区块链兼容以太坊智能合约
链客,专为开发者而生,有问必答!
此文章来自区块链技术社区,未经允许拒绝转载。
引言
随着区块链技术以及应用的普及,越来越多的区块链出现在大众视野中。由于区块链技术的开源特性,任何公司和个人都可以方便快捷的获取最新的区块链核心技术,通过对这些技术的选择和整合,最后开发和搭建满足特定业务需求的区块链产品。以太坊作为目前区块链2.0的杰出代表被作为诸多区块链项目开发的基础,甚至有人统计100个区块链项目中有94个是基于以太坊,而以太坊社区更是有25万的开发者在活跃着,因此以太坊成为大家争相研究和进行区块链开发的典型。EVM作为以太坊中重要的组件,其运行着以太坊上至关重要的智能合约,由于以太坊庞大的社区和经济环境,作为一个新出现的区块链兼容以太坊的智能合约逐渐的变为一种显性的需求,本文将介绍一个区块链兼容以太坊智能合约的思路和具体的实现。
实现思路
以太坊虚拟机作为一个图灵完备的虚拟机有其独特的优势和特点,这些在公众号之前的文章(区块链虚拟机技术简述)有所介绍。运行在以太坊上的智能合约实现了以太坊上丰富的应用,无论是发币、博彩还是游戏这些都离不开智能合约的运行,离不开虚拟机这个运行载体。如果你要开发一条新的区块链,无论你是否基于以太坊进行开发,虚拟机与智能合约的支持是必须要考虑的问题。为了吸引以太坊用户或者Dapp的开发和发布人员,同时也是出于基于以太坊对业务迁移成本的考虑,兼容以太坊智能合约往往都会写入到白皮书中。 对于兼容以太坊智能合约有以下两种实现方式:
编译器层面支持,支持将以太坊的智能合约编译成自实现的虚拟机可以操作执行的字节码
虚拟机层面支持,虚拟机支持解析以太坊智能合约编译成的字节码
通过简单的考虑,我们不难发现在虚拟机层面支持将是成本最低的方案。现在我们回到以太坊虚拟机,之前的文章有详细的介绍过以太坊虚拟机的实现和运行模式,对于每个智能合约的运行将创建一个新的EVM实例,这给我提供了一个思路:通过对以太坊虚拟机部分功能的剥离,这样我们就可以得到一个以太坊智能合约的运行环境,代码层面就是一个EVM的函数库。这样在新的区块链中,如果我们希望区块链兼容以太坊智能合约,我们只需要实现该函数库对外的接口,并将智能合约二进制码以参数的形式传递进去(这也是大多数虚拟机的方式),并以二进制的形式获得输出,这样我们就实现了对以太坊智能合约的兼容。 基于以上的思路,我们主要做了以下的工作:
剥离go-ethereum中的EVM部分代码为单独的工程
尽量的去除EVM中的对go-ehtereum的编译依赖
梳理EVM中运行的对外的依赖接口
提供一个完整的可以二次开发的EVM,即以太坊智能合约运行环境
以上工作过程中的主要原则是尽量的使代码有少的外部依赖,这样做的主要目的一是工程上方便实现该函数库的二次开发,二是减少使用者的二次开发成本。
具体实现
可以在github上获取该项目的源代码,你将得到一个最小的以太坊智能合约运行环境,github仓库地址为:https://github.com/XChainLab/evm-lite(欢迎star),工程下主要有三个目录:
crypto为加密函数库,函数库来源于go-ethereum,这部分单独出目录
kernal为以太坊虚拟机核心代码,实现了智能合约的运行环境,代码来自go-ethereum
demo为一个具体的使用示例
通过demo我们来演示如何让你的区块链支持以太坊智能合约
第一步实现数据访问接口
由于不同区块链底层依赖的数据存储不同,而以太坊智能合约中有对存储的操作,因此这里我们需要实现数据访问接口,接口的描述见文件kernal/statedb.go。 demo中我们实现了其中的部分接口,具体见mockstatedb.go,这里需要说明一下,demo中实现的是以太坊智能合约运行必须实现的接口,其他接口可以考虑不实现,必要的接口函数为如下:
GetCode(address kernal.Address)[]byte
GetCodeHash(kernal.Address)kernal.Hash
SetCode(address kernal.Address,data[]byte)
GetCodeSize(address kernal.Address)int
Exist(kernal.Address)bool
Empty(kernal.Address)bool
//关于snapshot的接口需要根据具体情况进行实现
RevertToSnapshot(int)
Snapshot()int
HaveSufficientBalance(kernal.Address,*big.Int)bool
TransferBalance(kernal.Address,kernal.Address,*big.Int)
除此之外还要实现一个链访问的接口,具体见kernal/chain.go,这里只需要实现一个接口函数即可
GetBlockHeaderHash(uint64)kernal.Hash
第二步创建EVM执行实例
具体见demo/runtime.go,这里主要工作是初始化相关的配置,该项目的原则上保留了以太坊的相关配置,使用者可以根据自己的情况设置其中的具体数值,demo中采用的均是默认值,使用者可以进行参考,创建EVM部分的代码如下:
funcCreateExecuteRuntime(caller kernal.Address)*kernal.EVM{context:=CreateExecuteContext(caller)stateDB:=MakeNewMockStateDB()chainConfig:=CreateChainConfig()vmConfig:=CreateVMDefaultConfig()chainHandler:=new(ETHChainHandler)evm:=kernal.NewEVM(context,stateDB,chainHandler,chainConfig,vmConfig)returnevm
}
第三部调用智能合约
在第二步中我们创建了EVM的运行实例,这里我们通过调用EVM的Call函数直接运行代码的方式来运行智能合约:
HexTestCode:=“6060604052600a8060106000396000f360606040526008565b00”
TestInput:=[]byte(“Contract”)
TestCallerAddress:=[]byte(“TestAddress”)
TestContractAddress:=[]byte(“TestContract”)
calleraddress:=kernal.BytesToAddress(TestCallerAddress)
contractaddress:=kernal.BytesToAddress(TestContractAddress)
evm:=CreateExecuteRuntime(calleraddress)
evm.StateDBHandler.CreateAccount(contractaddress)
evm.StateDBHandler.SetCode(contractaddress,kernal.Hex2Bytes(HexTestCode))
caller:=kernal.AccountRef(evm.Origin)
ret,_,err:=evm.Call(caller,contractaddress,TestInput,evm.GasLimit,new(big.Int))
iferr!=nil{fmt.Println(err)
}else{fmt.Println(ret)
}
这里我们直接将代码传递给了EVM,目前EVM对外的接口保留源代码中的各个接口,可以通过调用Create函数来实现创建一个智能合约。
编译运行
执行上面的demo十分的简单主要执行以下的几步操作即可:
确认你的机器上有golang的编译环境
git clone 代码到你的机器的任何路径,无需放到GOPATH下
进入demo文件夹,执行go build命令
运行demo即可
总结
本文通过以上的说明提供了一个让你的区块链支持以太坊虚拟机的思路和实现方式,并提供一个EVM的纯净版本供开发者使用,使开发者可以快速的在一天的时间里完成区块链对以太坊智能合约支持的开发,后续我们将结合目前区块链虚拟机技术的发展方向,来不断的提供对虚拟机通用化的技术支持和社区贡献。
相关文章:

Linux常用命令--网终设置
1、把自己(sa)添加到sudoers配置文件中,以便于获取权限 vim /etc/sudoers 编辑文件(部分centOS版本没有vim命令,则用vi即可) 找到【root ALL(ALL) ALL】语句,在下面添加: sa ALL…

python示例异常处理与程序调试_笔记:Python异常处理与程序调试
Python异常处理与程序调试Python提供了强大的异常处理机制,通过捕获异常可以提高程序的健壮性。异常处理还具有释放对象,中止循环的运行等作用。在程序运行的过程中,如果发生了错误,可以返回事先约定的一个错误代码。"try...…

js传入参数为字符串问题
示例: var device_mac"11qweq234ert";//第一种方式会报错:Onclick SyntaxError: identifier starts immediately after numeric literal,数字后面紧跟着字符这种写法只有device_mac是数字的时候是正确的。传入的为字符串则应该使用…

区块链热度背后的资本市场
链客,专为开发者而生,有问必答! 此文章来自区块链技术社区,未经允许拒绝转载。 进入2018年之后大家对于加密数字货币以及区块链等话题都各自有各自的意见和想法,很多人觉得区块链技术和加密数字货币是泡沫ÿ…

袋鼠过河(动态规划)
题目描述 一只袋鼠要从河这边跳到河对岸,河很宽,但是河中间打了很多桩子,每隔一米就有一个,每个桩子上都有一个弹簧,袋鼠跳到弹簧上就可以跳的更远。每个弹簧力量不同,用一个数字代表它的力量,如…

jenkins-svn配置
转载于:https://www.cnblogs.com/caer/p/5924337.html

python查看所有异常_如何获取python异常发生的实际行号?
如果你想按你描述的那样做from functools import wrapsimport sys, os, tracebackdef catch_exceptions(function):wraps(function)def decorator(*args, **kwargs):try:return function(*args, **kwargs)except Exception as e:exc_type, exc_obj, exc_tb sys.exc_info()prin…

区块链从一夜暴富到一夜暴“负”的辛酸史
3.15打假日,打假虽然年年有,但与往年有别的是,今年区块连技术得到了诸多重视以及初步发展,一些带有诈骗性质的数字资产交易所在用血腥的方式不断收割着更低层级的用户,而这些平台的受害者,却往往得不到任何…

iOS消息转发
消息转发是一种功能强大的技术,可以大大增加Objective-C的表现力。什么是消息转发?简而言之,它允许未知的消息被困住并作出反应。换句话说,无论何时发送未知消息,它都会以一个很好的包发送到您的代码中,…

python参数类型限定_python限定方法参数类型、返回值类型、变量类型等|python3教程|python入门|python教程...
https://www.xin3721.com/eschool/python.htmltyping模块的作用自python3.5开始,PEP484为python引入了类型注解(type hints)类型检查,防止运行时出现参数和返回值类型、变量类型不符合。作为开发文档附加说明,方便使用者调用时传入和返回参数…

CentOS VMware 配置IP小结 静态 配置 桥接 NAT
系统启动后可先ping下外网或局域网内其它机器。如果配置虚拟机时选择的NAT上网方式,后面需要配置固定IP,请先参见VMware NAT方式下设置静态IP获得可用的IP范围和网关等信息。先将ifcfg-eth0备份到home目录下,不要放在与它同一目录下ÿ…

区块链简史:解读这场技术革命的前世今生
链客,专为开发者而生,有问必答! 此文章来自区块链技术社区,未经允许拒绝转载。 真格基金徐小平的一个“内部讲话”被泄露,揭开了创投圈对区块链的新一轮热衷。 在这份微信群的“内部讲话”中,徐小平把区块…

IncDec Sequence(codevs 2098)
题目描述 Description 给定一个长度为n的数列{a1,a2...an},每次可以选择一个区间[l,r],使这个区间内的数都加一或者都减一。 问至少需要多少次操作才能使数列中的所有数都一样,并求出在保证最少次数的前提下,最终得到的数列有多少种。 输入描述 Input…

C++ 中set
set特点: 所有元素不会重复,重复插入已经有的新值无效;所有元素按顺序排列;unordered_set除外键和值相同,所以set中的值是不可更改的set的各成员函数列表如下: 1.begin()--返回指向第一个元素的迭代器 // 如果当前容器…

python自动排课表_【python-leetcode210-拓扑排序】课程表Ⅱ
现在你总共有 n 门课需要选,记为 0 到 n-1。在选修某些课程之前需要一些先修课程。 例如,想要学习课程 0 ,你需要先完成课程 1 ,我们用一个匹配来表示他们: [0,1]给定课程总量以及它们的先决条件,返回你为了学完所有课…

简单粗暴告诉你什么是区块链
链客,专为开发者而生,有问必答! 此文章来自区块链技术社区,未经允许拒绝转载。 区块链是什么?它是如何工作的? 比特币已经成为现代互联网的潮流 - 随之而来的是区块链。人们说区块链技术将导致互联网运作…

【Codeforces】Round #375 (Div. 2)
Position:http://codeforces.com/contest/723 我的情况 啊哈哈,这次raiting肯定要涨,接受过上次的教训,先用小号送肉,大号都是一发切,重回蓝咯 结果。。。 FST!! 不,这次是skip&…

python的matplotlib背景线_python中matplotlib的颜色及线条 控制
https://www.cnblogs.com/darkknightzh/p/6117528.htmlhttps://blog.csdn.net/qq_34337272/article/details/795555441.设置栅格(1)使用pyplot api命令打开栅格:plt.grid(true)设置栅格格式:plt.grid(colorr, linestyle--, linewidth1,alpha0.3)(2)使用axes类面向对…

系统权限设计思路
权限系统通常包括如下基本元素:用户、角色、权限、资源、操作。 角色分类:总经理、部长、员工。(在实际中一个用户可能存在多个角色,这就要考虑到权限累加处理) 权限分类:如”员工考勤权限”、”审核权限”…

“区块链”究竟是什么
链客,专为开发者而生,有问必答! 此文章来自区块链技术社区,未经允许拒绝转载。 什么是区块链? 说到区块链,就不得不说比特币。 2008年底,比特币之父中本聪发表了一个关于他研究的电子现金…

leetcode 179. 最大数
给定一组非负整数,重新排列它们的顺序使之组成一个最大的整数。 示例 1: 输入: [10,2] 输出: 210 示例 2: 输入: [3,30,34,5,9] 输出: 9534330 说明: 输出结果可能非常大,所以你需要返回一个字符串而不是整数。 自己写了很久的比较函数,时钟有…

cf-Sasha and Array
题目链接 http://codeforces.com/problemset/problem/719/E 解题思路 矩阵上的线段树。 因为矩阵有分配律(AB)C AC BC,所以计算总和时直接把增量矩阵乘上去就行了。用矩阵快速幂。 fib的计算尽量拉到主函数计算。 代码 #include<stdio.h…

实对称矩阵的性质_浅谈矩阵的相似对角化(一)
森屿瑾年:浅谈线性变换和矩阵之间的关系zhuanlan.zhihu.com通过前面的讨论,我们引出了线性变换在不同基下的矩阵之间的关系,知道了线性变换在不同基下的矩阵是相似的,进而我们可以通过选取不同的基,使得线性变换在这…

区块链技术未来可能用于哪些方面?
链客,专为开发者而生,有问必答! 此文章来自区块链技术社区,未经允许拒绝转载。 当世界上从100比特币购买25美分的比萨饼,到一比特币兑换4800人民币的天价,在这风起云涌的纪念,我们见证了一个…

tomcat启动
tomcat的启动一般是从startup.bat/startup.sh开始,然后启动catalina.bat/catalina.sh,然后启动bootstrap.jar包 那么它们启动的时候都做了哪些事情呢? 首先是startup.bat,startup.bat做了什么? 第二是catalina.bat&…

ERROR: from PIL import Image ImportError: No module named PIL
ERROR: from PIL import Image ImportError: No module named PIL 到 http://www.pythonware.com/products/pil/ 下载相关支持的版本 我的是python2.7 直接打开,然后一路按“下一步”,就行 转载于:https://www.cnblogs.com/jakejian/p/8992…

python中font_Python ColorFont包_程序模块 - PyPI - Python中文网
控制台打印彩色字体0 黑色 8 灰色1 蓝色 9 淡蓝色2 绿色 A 淡绿色3 浅绿色 B 淡浅绿色4 红色 C 淡红色5 紫色 D 淡紫色6 黄色 E 淡黄色7 白色 F 亮白色格式:0x12高位代表背景色,低位代表字体颜色0x10 | 0x020x10代表背景色,0…

区块链技术到底有啥用?
链客,专为开发者而生,有问必答! 此文章来自区块链技术社区,未经允许拒绝转载。 前言:关于区块链适合做什么和不适合做什么?一直都有争议。那么,通过什么方式来辨别呢?本文用详细的…

博客作业04--树
一.学习总结(2分) 1.1树结构思维导图 1.2 树结构学习体会 树的前中后序递归操作的访问路径都如下图 树的层次遍历的路径则如下图 操作{ 进队第一个节点, while(队不空) { 访问该节点, if(BT->lchild!NULL)进队。 if…

oracle数据如何获取游标中动态字段_如何实现报表数据的动态层次钻取(二)
上一篇《如何实现报表数据的动态层次钻取(一)》介绍了利用复杂 sql 实现动态层次结构的方法,但该方法依赖 Oracle 的递归语法,在其他类型的数据库中难以实现。要想通用地实现此类报表,可以使用下面介绍的“集算脚本 本…