自己实现 Etherscan 合约认证功能

最近要实现Etherscan的合约认证的功能 类似这个这个页面
大概实现思路是这样

  • 1.用户在页面输入合约代码,以及编译时的参数信息,和被认证的合约地址
  • 2.提交信息到webServer,服务端使用提交的参数信息,调用编译器进行编译获得字节码
  • 3.通过eth_getCode() 获取被验证合约的链上合约字节码与提交的合约字节码进行匹配如果一致则认为验证成功
解决的问题
1. bytecode尾部与链上的bytecode不同

bytecode尾部是一个部署合约元数据的Hash称为 AUXDATA ,不同环境下编译会产生不同的hash(即使使用相同版本编译器),在校对时候需要移除尾部的32字节Hash值

2.bytecode首部与链上的bytecode不同

在编译完成后bytecode首部的一段代码称为部署代码,这一部分在部署完成后通过eth_getCode 是无法获取到的,所以在比对时需要将它移除出去,那么怎么确定哪一部分是属于部署代码的呢?
经过观察发现,部署代码的最后一个指令都会以STOP结尾(不一定正确),在编译合约时同时生成opcodes,编译完成后将opcodes读取进入,截取出opcodes第一个STOP指令前所有的指令,计算出这些指令对应的bytecode,然后将其移除出去,由此又衍生出关于opcodes转bytecode的第三个问题

3.opcdoes转bytecode的问题
  • 指令转换问题
    发现通过opcodes计算的bytecode有时候对有时候不对,问题出现在PUSH指令上,PUSH1 到PUSH32 分别表示操作1到32个字节的数据,那么后面的数据如果不满足PUSH指令的数据长度,需要在高位补充0
  • 源代码指令不够问题
    由于部署代码部分需要自己进行计算,所以需要收集所有的opcodes,以太坊源码 中指定的opcodes在实际使用过程中发现并不完整,经过核对有INVALID,KECCAK256 操作码并没有在该源码文件中,手动录入
  • 库合约字节码被替换问题
    库合约部署完成后,bytecode开头(已经去除了部署代码)使用了PUSH20指令后面紧随合约地址,编译器刚编译完成后当然是不知道合约地址的所以PUSH20指令后面跟随的是空值也就是 0000000000000000000000000000000000000000,检测到后需要替换为真实合约地址

参考文档
https://www.jianshu.com/p/1969f3761208

solidity历史版本下载 nightly版本不知道在哪儿下载,有知道还望的告知一下

附所有opcodes
{
    "STOP": "00",
    "ADD": "01",
    "MUL": "02",
    "SUB": "03",
    "DIV": "04",
    "SDIV": "05",
    "MOD": "06",
    "SMOD": "07",
    "ADDMOD": "08",
    "MULMOD": "09",
    "EXP": "0a",
    "SIGNEXTEND": "0b",
    "LT": "10",
    "GT": "11",
    "SLT": "12",
    "SGT": "13",
    "EQ": "14",
    "ISZERO": "15",
    "AND": "16",
    "OR": "17",
    "XOR": "18",
    "NOT": "19",
    "BYTE": "1a",
    "SHA3": "20",
    "ADDRESS": "30",
    "BALANCE": "31",
    "ORIGIN": "32",
    "CALLER": "33",
    "CALLVALUE": "34",
    "CALLDATALOAD": "35",
    "CALLDATASIZE": "36",
    "CALLDATACOPY": "37",
    "CODESIZE": "38",
    "CODECOPY": "39",
    "GASPRICE": "3a",
    "EXTCODESIZE": "3b",
    "EXTCODECOPY": "3c",
    "BLOCKHASH": "40",
    "COINBASE": "41",
    "TIMESTAMP": "42",
    "NUMBER": "43",
    "DIFFICULTY": "44",
    "GASLIMIT": "45",
    "POP": "50",
    "MLOAD": "51",
    "MSTORE": "52",
    "MSTORE8": "53",
    "SLOAD": "54",
    "SSTORE": "55",
    "JUMP": "56",
    "JUMPI": "57",
    "PC": "58",
    "MSIZE": "59",
    "GAS": "5a",
    "JUMPDEST": "5b",
    "PUSH1": "60",
    "PUSH2": "61",
    "PUSH3": "62",
    "PUSH4": "63",
    "PUSH5": "64",
    "PUSH6": "65",
    "PUSH7": "66",
    "PUSH8": "67",
    "PUSH9": "68",
    "PUSH10": "69",
    "PUSH11": "6a",
    "PUSH12": "6b",
    "PUSH13": "6c",
    "PUSH14": "6d",
    "PUSH15": "6e",
    "PUSH16": "6f",
    "PUSH17": "70",
    "PUSH18": "71",
    "PUSH19": "72",
    "PUSH20": "73",
    "PUSH21": "74",
    "PUSH22": "75",
    "PUSH23": "76",
    "PUSH24": "77",
    "PUSH25": "78",
    "PUSH26": "79",
    "PUSH27": "7a",
    "PUSH28": "7b",
    "PUSH29": "7c",
    "PUSH30": "7d",
    "PUSH31": "7e",
    "PUSH32": "7f",
    "DUP1": "80",
    "DUP2": "81",
    "DUP3": "82",
    "DUP4": "83",
    "DUP5": "84",
    "DUP6": "85",
    "DUP7": "86",
    "DUP8": "87",
    "DUP9": "88",
    "DUP10": "89",
    "DUP11": "8a",
    "DUP12": "8b",
    "DUP13": "8c",
    "DUP14": "8d",
    "DUP15": "8e",
    "DUP16": "8f",
    "SWAP1": "90",
    "SWAP2": "91",
    "SWAP3": "92",
    "SWAP4": "93",
    "SWAP5": "94",
    "SWAP6": "95",
    "SWAP7": "96",
    "SWAP8": "97",
    "SWAP9": "98",
    "SWAP10": "99",
    "SWAP11": "9a",
    "SWAP12": "9b",
    "SWAP13": "9c",
    "SWAP14": "9d",
    "SWAP15": "9e",
    "SWAP16": "9f",
    "LOG0": "a0",
    "LOG1": "a1",
    "LOG2": "a2",
    "LOG3": "a3",
    "LOG4": "a4",
    "PUSH": "b0",
    "DUP": "b1",
    "SWAP": "b2",
    "CREATE": "f0",
    "CALL": "f1",
    "CALLCODE": "f2",
    "RETURN": "f3",
    "DELEGATECALL": "f4",
    "SELFDESTRUCT": "ff",
    "REVERT": "fd",
    "INVALID": "fe",
    "KECCAK256": "20",
    "SHL": "1b",
    "SHR": "1c",
    "SAR": "1d",
    "RETURNDATASIZE": "3d",
    "RETURNDATACOPY": "3e",
    "EXTCODEHASH": "3f",
    "CREATE2": "f5",
    "STATICCALL": "fa"
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,589评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,615评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,933评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,976评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,999评论 6 393
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,775评论 1 307
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,474评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,359评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,854评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,007评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,146评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,826评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,484评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,029评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,153评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,420评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,107评论 2 356

推荐阅读更多精彩内容