\xb5\xbcv\x84\x92\v\xcf\u060f\xe0w\x15\xa1\u02c4\x9c\xa3\xb4P0r\xc0\xc8\tFNj@.\xd2\xdc\xc0\xc2ILk\xe4\xbd\x19\xe8\xde\x14\x88\b\x8b\x0f\u078d\x9b>\xfc>|\xed}W\xe1\xee/^\xe3\x81|,\xfeNy\x97O\u71cb\x0e\x1e\x9dLmj\xf6\xd6\x03L\xf5\n\xdc\x04N\xdco\x9cT\xdbW\x89\xc2\xe8=|'Ck\r\u055d\x02 \x18,\xec\u0093w\u0742\a\xbe\xfd\x05\x89\xc7\u007f\xf4]\xac>\xf9\xc4\x1a\xaf?\x05\x1fr\xb2\xb6\x18\xb9u\xeb\xd7g\xc7<\xfb\xd9\u063c\xf9\u87dey\xe6\xf3\xff\xdb\xdb\xdf\xfe[\u007fCD%\xa1\xfew\u007fw5]~\xf9\xeb\xe4\x99t}O\xc0|?_\x9f\xfc\xe4?\"J\xb0\xbe\xfa\xd5/\x9fu\xd5Uo\xfa\xd4\xddw\u07fdqO\xbf\xb3\xf5\x97\u07ccs\xff\xaf\xff\x86a\xbf\x0f\xe3\xbc\xe6\xc0%~\xdee\xf5\x89\xb4\x8a[;\x977\xf5\aA\x00s\xae\x02\xdek\r\xb8\xe8\u0451zm\xd5\xf4\xdb4\x0e\xf0.i\u6943N\xa9\x94\xb2)\xb3k\x1bY\x97\x96*|\xefT\xc5\u068a\x17\x91q*\xa6mx\x96\x1a\xb4Jk\xc61\xa1\xe6E\xd2\xd4\xfbKc6\xaa\x91i\f\x91\x8a\u058a?\xdf\u059c\xe6@\xa3\xa8D\xaa\x19u\xe21\xc4\u00c6\xc1\x1e\x13\xbc\xe6\u0460Q$\xd26Toz\x131\xf2\xde\f\xc4\x19,\x1b'\x9cp\xc2\xe3\x17\\p\xde'\xae\xbc\xf27\xff\x84\x88\x1eM\u007f\xe7\xc6\x1b\xbf\x87\xe7?\xff\xccg\u0735>\x01\xf3g\xc0\xfa\xad\xdfz\ab(\xed\u55ff\xe6=\xd7_\xff\u03ff\xbfc\u01ce1\xfca\xe5#\xe3\x9e\xf5\x9c\xad\xb8\xf4?}\n\a\x1c\xbd\x19+\xbb\x97|\xb2O\xe9\xa1RM\xbb\xa4\x81p\xcdj=\x8eo\xa3\x99l\x8fj\x80\xa4\xe4\xe0\x13\x80\xb1\rpX\x8b\n\xdf\xe3\x9c\u0358\u007f\xeb\xdaMPZk\x8eH\xc6\xf9c\xd9\x03\xc5Q\xbb\xfd\xda\xff'\u05b9\te\xd5\u49db\xf7W5\x1b\x83\xdb\xe0\x1a\x9b\x95\xb4\x9cL\u0186_\xd1p/\xa0\xea=\xe2F\u056e\x89\x02\x95\xe2}T\xac\xab\xde,\x17\x14)#G\xb0.\xd17%Fk\xe9f\xcb\xf1\x15P\ny\xb7\v3\x1aa\xe7Oo\xc3#?\xf8:\x1e\xf8\xe6ux\xe2\xf6\x9bP\xac.\xb5\x03Sp\xe3,CK 8\xe4Y\a\xe3\xb8\xe3\x8e\xdbu\xce9g\xff\x8f\xdf\xff\xfd\xf7\xfd\x15\x11\u0756\xfe\u03bd\xf7\u0783g?\xfb\xd8g\xecu>\x01\xf3g\xc0\xfa\xc8G\xfe_\xfc\xfa\xaf\xbf1\x80\x89\x1cp\uee7f\xf0\xc9o~\xf3\x9b\x17:\xd7\xeeq\xca\xcc8\xe1\u016f\xc1\x19W\xbe\x17sG\x1e\x8b\xe1\xb0@Q\x14\x10g\xe1b-^*Y\xa8\x01\xec\xd5m\xa9\x84\x03\x88\xba\xe3X\u5e44#\x8f|y\xe4mC&\xd1X\xc5\f\xaa\uedd5{nC\xf9\xa6\xcdk\v\xa72\xc6}\xaf\xc5\xe7\xa0e\x02\xb26\xfe)\xf5\r\xa3\xb4}\xa5\xca\u05e6e\a\x8aI;M@\x8f\x9e.\xdeU\xb0\xb1\xb1H;\xdf.\xc9k]\xbe\xee\u912bT NR\u077f\"Ow\xe9\xa0\x15\x8f\x16\u0205\x93\x92B\x89\u0787\"\xd28uH\xa9\x18W\xd1\x06\x81\t\xac2\xe8N\x0ek,\x1e\xbf\xed{\xb8\xef\x9b\xd7\xe1\xc1\xef\u0740\x9d\xf7\xfc\b\xb6\x18\xb5\xa2Q\x19p\x12\xde\xebLkt{\x1d\x9cx\xc2\t\u063a\xf5\xb9?\xb8\xe0\xfc\xf3\xdf\xf1\xcaW\xbd\xfa\xeb\xe9\xaf\xfd\xdd\xdf]\x8d\xcb/\u007f\xdd3\xfe:\x9f\x80\xf93d\xfd\xf8\u01f7\u2913\x9e\v\x00\xf8\xda\u05fe\xb2\xf5\xfd\xef\u007f\xff\u05ef\xbf\xfe\x86\xb9Vr84\x167m=\a[^q%\x8e8\xfbE\xe8\x1e\xf8,\x18\xe3P\f\ap\u0468\xab\x85w\x8d\x00V\xafM\xa5\xf4\xb3\x8eG\xf8\xf8;&\xe1\xc7K\x87\xbb\xa4t\x96\x96t\x84\xb1\xea\xbcm\x80\xa6\r\xe9Z\x88\xf65\xbdRP\xc9\xef\x9a\x00\xdb\x1c\xe0\u065b>[jS\xad\xd5\xf3\xad\x03yx\xf6m\x8a\x97\xb0\xf9U:q\n\x95\xaf\xff\xa6kP[Q:\x18+\xed\u0606\xb4e\xe5N5\xc0\x8f\xf7i\xa4\xd2RF\x8f\x1eA4.KN\x19\xa8d\x89\x11\xc0\xe3\xaeKD\xe0,\x83\xce;p\xd6b\xdb\x1d?\xc4\xdd_\xfe\x14\xee\xff\xe6ux\xf2\xbe\xdb\xd1\xf4\a\x8a\x0f\xa0\x04p?\xf5C\x9dN\x8e\x99\xe9\x19l\u06b4\t\xcf{\xde)\v'\x9ex\u009f\xfc\xd6o\xbd\xf3CD\xb4\v\x00>\xfe\xf1\x8f\xf1k_\xfbknreO\xc0\xfc\x19\xb9n\xba\xe9\xfbt\xdai\xa7\v\x00|\xe2\x13\xff\xf0\x92\xff\xfc\x9f\xff\xeb5\xdf\xfe\xf6wf\xdb>\x16\x14F\xfa\xa7\xd6o\xc0\xc6\u7783\x13^\xf6F\x1cv\xea\xb9PS3\xb0\xc6\xc1\fVk\x8d\xae\x8a\xb2\x90\x06\x8f^\x81I\x12(_\x1bXI\xc1\xbcf\xb0DU\xd5O\r\xad\xf2ZMKip\xed\xcd\x1fn\xca'E\x9a\xbe1\x82*\xbb\xa1\x82cn\xb1*H=l\u02a1\x9e\xf0}\xa6\xf1\xfec\x94]J\xa8d\u02f0\x86\xe4a\xa6\x1b\x9dC}X\b\t\xe0\u01e0\xb44\x06/Fw\xc6\u7903\xc3c\xf4\b72\xde\xe5\xb0R\xdf\\R\x8a\xab&-M^\u0426\xb5B\xa9Ya\x8dNo\n\"\x82'\xef\xbb\x1dw|\xe1\xbf\xe3\xbeo~\x1e\xbb\x1f\xb8\x13f4h1\x81!\x1f$\xce\f\x11'\xe2\x84\xe6\xe6f1;;\x83C\x0e9\x14g\x9f}\xe6\u03a3\x8f>\xfa/^x\xf1%\u007f{\u0496\x93\x1e\x04\x80W\xbe\xf2\x15\xea\x13\x9f\xf8\x94\xdd_\u0331&`>Y\xff\xcb\xeb\xaf\xfe\xea/\xf8Moz\x8b\x03\x80\xab\xaf\xfe\u0605\x1f\xf9\xc8G\xae\xf9\xcew\xbe\xbba4\x1a\x19\xa5\x94\xb2\u05b5\xea3f\x0f9\x1c\x87\x9dz.\x8e\xb9\xe8Wp\xe8\xd6s\xa0{3(\x06\xabp\x81\x96i~\xa4\u04a37S\x134+d\xa5\x06\xa7]w\xf1\xab6\x95\xa6\xba\xa5\xc9\x17\xd7\x14\x19M\xab\xdb=\xad\x06h1\x118\xdcge\x0e\x15\x81\x8f\xcaA\xa7X\xc4:Y;u'\x1d\xb2\xa9\x01:\u0579\xf9\x96t\xb9\xbd6C}\x90\x03\x95\x9bb\xc6\x04\x15\xc0\x19\xa5\xc5,\xd5\f\u04cc\xabd\xa4\xae\xda&\x91\xe4\x8d\xd4\r\xba\xa4\x02o$\x9b\x05\xa5\xd2$q0\u0387C\xe4\xdd\x0e\x96\x1f\u007f\bw\xdf\xf0I\xfc\xf8\u068fc\xe7Oo\x83\xb4T\xe2Q\x99\xa2\x98\xc59g\x8c)p\xd0A\af\x1b6\x1c\x8c\x83\x0f>x\xfb\x19g<\xff\xd6\xd3N;\xf5\u00ff\xf2+\xbfz\x1d\x11-\xc7\u07fb\xfa\xea\x8f\xd2\xeb^\xf7z\x99\\\xc5\x130\x9f\xac\xb0>\xf4\xa1\xbf\xe4\xdf\xfc\xcd7;\x00\xf8\xf4\xa7?y\xc1\xd5W_\xfd\x0f\xdf\xfa\u05b77\xec\xdc\xf9$\x98\u0649\b\xa7>.13\x93\x94\xc6\xf4\xc1\x1b\xb1\xf9\u0717\xe1\x84\u02ee\xc0\xfag\x9f\xfc?\u06fb\xd2\xe0:\xaa3{\uef7d\xbcE\xfb\xd3\xf2$\u02ca6\x8c\x1d/x\x19\xc6\xc66v\x8c\x1c\x98\x94\xcb\xd4\f\x1e\x02\xe4G25E\xe18\x19\xa8\u0250T`H\x82a\x96\x84Jf\x8a\u0270XP@\xa8\n!\xc9\x04\xc8x\x02\x89\a\x13\x1b\xe3\x15\x19[\xc6c\xcb\xd6bY\x8b%\xdbOz\u04b3\x96\xb7t\xf7\xbd\xf3\xa3\xbb_w?=9T*\x10\x92\xf4\xf7G\xb6\xf4\xd4oQ\xdfs\xbf{\xbe\xf3\x9d\x0f\x86a@OM[G\xe5\x1c\x8b\u05dc\xbc\xd3[\xfa\x83\x8bs\xc7\fj\x06\xee6}\v\xa0DNES\xe4aT\x80Y\\\r?\xc0\x02p\x80\xdb\x04t\x99\xda\xca\x0e\x93;\xd6sN\x10N\x929s\xd7\x103\xb2~GuCs\x00\xde\xfe\xbf\xbd9\xe4\xb6\xf0\xbb\xaf\u0248\xa3\xef'\xd9l\xdetx\xb4\u01aaZ\x80k\xda\xc9\xdat\x89\xbb{\x96{\x8a\xc1b\xc6)\x04\x96~\xdcV\xbc\x10\x97g\x8b\xd3[`\x1e\x9f$E\x85\x12\n \x99\xb8\x82\xc1\xf7\xf6\xa1\xfd\xa7O\xa1\xef\u0777\xf2r\xe2\x84R\xd3\b\x8b1\b\xce\rn\x18,\x12)CCC\x03\xaa\xab\xab/,\\\xb8\xf0\xf5\x96\x96\x96\xc7ZZ6\x9es\xff\xde7\xbf\xf9\x10Y\xb6l\x99\xb8\xed\xb6\xbf\xf6\x17\xaf\x0f\xe6~\xe4\u01b7\xbe\xf5M\xf2\xe8\xa3\xff$\x00\xa0\xad\xed\xf0\x86\x1d;\x9e\xf9\xcf\xfd\xfb\x0f,s/\x01\xaf\u0305\xe4\xe4\xa2\xc45\x9d&\x97\x1b\xcf*'0\xcb88\u0324C\x90\x876\u0235\x17\x80\u02e6\xd56\xf9\xa2\xc4\xecj\x14 \x969\x94p\x81\"q\x15\x05\x85\xd7\u070b\xe4Q\x9c\xe4\xd0\x14\x94\x98\xf2=B\xecY\x1e\xf6\xa7 r\xe4\x92\xe6\xc6B@\xac\xe767\x99,\x03\xef\xca\xfeM\x1bY1\xc3\u01c6\xbbOA\xc8\xd5\xec\v\xab\x17\x80xL\xbe$\xd7H;\xee\xca\u0429e\x8aEe\x19JH\x8561\x81\xe1\xe3\xef\xa0\xe3\xcdW\xd0\xf5\xf6N$\xc7F\xf2\x838\xa1`\x8cZ\x9b\tGEy\x05\xe6\u039d\x8b\x9a\x9a\xe8\xb1\r\x1b6\xec\u07f6\ud2ed\x8a\x12<\xed\xfe\xbd\x05\v\xaeEkk+\u05ad\xfb\x94\xbf`}0\xf7\xe3j\xf1\xe0\x83_'\xdf\xfe\xf6cV3\xa5\xa8\u07fe\xfd\xe1\xc7\xf6\xed\xdb\xf7\u064e\x8e3\x88\xc7\u3982\u015d\xa1Sj6n\x00\xe0Z\x06\xc1\xb2J\xd4\u07f8\tsW\u0742\xaa\xeb\u05a00Z\vC3`his\xaa}\x0e\xaa\x12\xe1:\xda\xc3\xd5\xe5\txG\xb3[w\xa6c\x80\ubc3c\xd9\xd6~kX\xb4\x10\xb3\xdf\xd0\xf9\x9a\x98\xf2\xb5\xc5S7\x9dB\\\xad\xed\"\xbf.\xfb>bg\x8ea\xe4\\\a\x92c1\xa4\xa7&\xc0\r}\xc6\xe7I)\u02f6\u061b_\xad\xb1mB\x18\xe9t\x9a\x97\x95\x95\xc9s\xe6\xd4`\xfe\xfc\xf9\xf1\x95+\xff\xfc\xdf\xee\xbf\xffk\xdf%\x84d\xc7\x02}\xe7;\xffJ\x1ex\xe0\x1f}y\xa1\x0f\xe6~|T\xf1\xea\xab?\xc3\xee\u077b\xc9SO\xed\xc8.\xbcw\xde\u0673\xf1\xe5\x97\u007f\xf2\x8d\xe3\xc7O\xac\xef\xec\xec\xc4\xe8\u8a1d\x9cR\x0f\x8d`\x1d\xbd\x05\u7812\x84py\r\xe6,[\x83\xba\x1bnA\xe5\u0095(\xaem\x02Q$\xe8i\u00f4\b\xe0\x1c\x82\xebV\xd6\xeed\xa6\xe6\x14!W\xcb\xd1U-\x02\xf3\xd3(\xf4K\xd5\x00\x00\v\xecIDAT\"\x1e\x83+K\x8d\xe1\xc9\xfc\x89\xfd\xe2g\aL\x9b\xe20r&M\xb8\x9b\x99f{\x1dW\x1b\xd6\xecH\xfeL\x12;+[\xb4~n\xb8\xb2\xf3|\x1c8r\b!\x02\xaf2\x881\x06EU!)\x12\x88\x00\u04898&c\x171q\xb1\x0f\xa3\xbd\x1d\x88u\x9d\xc4\u04296\\\x19\ua0de\x9a\xc2\f{\a\xf7\xe9\x8b8~\xf2\x0emC@\b\x11\x9a\x96\xe1\xa1P\x98\u035bw\r\xea\xea\xea\x06\x97-[\xba\xf3\xcb_\xfe\u04bfG\"\x95=\xeekuvv`\u07bc\x05\xfe\xe2\xf2\xc1\u070f\xdfG\xb4\xb6>\x8d\xad[\xb7\xb9\x8e\xf9B~\xe9\xa5\x1f\u07bdk\u05ee;\xfb\xfb\a\u059dF\xb2lR.yd\x83e\xd6\xf8\xca*\x80:\x1b\x94p\x9aw(1\x1b\xf8)\x01\xb3(-JMb\x852\n\x89\x02Z:\x83\x89K\x03&h\xf7\x9e\xc1X\xdfY\x8c\xf5wc|\xa0\v\x13\x17\a\xbd\xe3\xe0(3yn\xeb\x14E\x89W\xc6#\xf2\fN\x15B\x80R\x02YV \xcb\x12\x1a\x1b\x1b\xd1\xdc\xdc<\x19\x8dV\xb5\xdeu\u05dd?Y\xb5jM\x9b\xfb\xf1\xdf\xff\xfe\xe3\xb8\uffbf\xf7\x17\x90\x0f\xe6~|\x9c\xe2\x95W\xfe\v[\xb6\u070e#G\x0ea\u03de\xbd\xec\x81\a\x1e\xb4\x95/U/\xbf\xfc\u04a7\xdb\xdbO\xdc\xdd\xd6vt\xfd\xa9S\xa7\x90H$\x90N\xa7=L\xc5L\n\xc603hj\x82<\xa1\x14L\x0e@\t\x17A\n\x85!\a\v\xa0\x84\x8b\xa0\x16\x95!\x14\xa9B\xb8j.\xc2\x15s\x10(.\x85\x1a.B\xb0\xb8\x14\xc1\x92\n\xa8\x85%\x90\x14\x15\xce \x04\x0eC7\xcci\xedB\x98\x13L\x05\xcf\x0e\f\xa6\xd4\xd2e\u00dc\x96\x03 ;\xcb\xd46\xb0\u02b5\x9b\xe5B@\xe3f\xe1\xd5\x00\xcd\u038c\x13v\xeaL\b\xe0\x18E\xb9\xc6\u06f9\xac\xa9,>\u01b1\x036\v\xae\xb6\xbe\x9c\x11\xc7!\xd11,s\rL&f\x87'\x17\x02\f\xe6&\x96\x99\x9e\u0115\xe1~\x8c\xf5w\"~\xfe,F{;\x90\x18\xee\xc3\xc4\xf0\x00&b\x17\xc0u\x87\xf3\xa6L\u029aY\x99\xb2A\xe21\xf52\x9d\x10E\xdeF,\xc30\x04!\x84\x84B!\x14\x15\x15\xa2\xb1\xb1\x11\x8b\x17/>\xdd\xd4\xd4\xf8\x8b\xa5K\x97\xbd|\xd3M-\xed\x00\xb0~\xfd\x8dt\u06f6m\xb8\xf3\xce\xcf\xf9\xea\x14\x1f\xcc\xfd\xf8C\x897\xde\xf8\x05}\xe3\x8d_\xb2'\x9ex\xd2V\xbe\x84\u007f\xf0\x83\x176\x1f=\xfa\u07b7\x8e\x1e=\xba``\xa0\x1f\xb1X\f\x9a\xa6\xe7-\t\xba\xb3C\x13\xe0I6\xd3\x16\x82Cp\xd7\fw\xca \xa9A\u0221\x02H\x81\x10\xa4@\x10J\xa8\x00\x81\xc2R\x84\"QD\x1a\xe6#\u04bc\b\xa5\x9f\xb8\x16\xe1\xb2JH\x8a\nI\x92 I\xd41\xc4\x12\x00\xb8\x01\xce-B\xc5eW\xeb1\x8d\xb2\xa8\ffm2 \x04\x19\x01d,x\xd2\f\xb3\u02d2[\x1bD\x96\n\xe2\xe6\tA\b\x93'2\xbf\xaf\xc3\xd0\xd20\xd2Ip]\x03\xd7M\x1baSJHA\xc0A\xb9n\x82\xb3\xaeA\x18:\fC\x03\x84\x80\x1a.\x82\x1c\f\x9b\x12A-\x8d\xf4D\x02S\xf1\u02d8\x8c\rc\xf2R?\x12\xc3\x03\x98\x8a_F*1\x8aTb\x14\xc9\u0118\xc7\a\x85P\x06\xcaXv\x93\xb3\v\x964\x0f\x80C\x88\x19\x12Ka\x06!\x04(**FYY\x19\xae\xb9\xa6\x19MM\x8d?^\xb0`\xc1\xd3\u06f6}\xb9\x8b\x102l?]k\xeb\xd3l\xeb\xd6m\xba\xbf2|0\xf7\xe3\x0f4\xac\x81\xd1n\xe5\vmm\xdd\xf1\xb9\u00c7\x0f\xdf\u007f\xf2\xe4\xff-\x1d\x19\x19\xc1\xf0\xf002\x99\x8cA\b\x04\xa5L2\v\x9d9\x1c\xac\xc5E\x10\xf7\x84g\xe7\xa2\x10\xdc\u021b5RJ!\a\xc3P\vK\x10,-G\u025cFT^\xb3\b%\xd1Z\x14\x94U \\Z\t\xb5\xa8\x14r(\fI\t\x80I2d\x89\x81P\xe6iN2\v\x8f\xe6f\xc2u\x03\x84\xeb\xa0\xe0\xa000\x9d\xd611\x95\xc4\u0115+\x98\x1a\x1f\xc5\xd4D\x02\xa9\xa9\t\xe8\xa9$2\xa9\x142\x13cHO\x8cCKN\xc2H\xa7`d\xd204\xf3\xab\x9eJ\x82k\xa6m\xb00\f\ap\xadZ\x02\xb1\xc0\x94s\xdd,\x06\x1b\xe6\xfb\xb4\x1b\xb3\f-\x03\xaee\xa0k\x19\xf3\u07fav\xf5\x05\x9d\x95\x8bRPP\xc7\xc7\x1c\x8e\u01ce;\x03'\xc43(\x9b\xeb\xban\b\xc1%UUI$\x12AYY\x19\xae\xbdv~b\xf9\xf2\xa5\xaf/_\xbe\xec_n\xbe\xf93\x1e>\xfc\xb5\xd7^!\xd5\xd5Q\xb1j\xd5\x1a\u007f1\xf8`\xee\xc7\x1fC\xec\xdc\xf9sr\xeb\xad\u007f)r8\u04ed\x1d\x1d\x1d[\xbb\xba\xba\xe7\x0f\r\r\x05c\xb1\x18\xe2\xf11!\x047\b\xa1T\bn+(H.\x1d\xe3\xf6Gw\xeeT\xe2\x92\xf59\xed\xa3B\x18.\x87?\x02I\r\x80\xc92\x98\xacB\t\x86\xa0\x14\x14\xa1\xb8\xbc\x1a\x85\x955\b\x16\x95@\r\x86!)*\x18\xa5Y!$#\x020t\x18\x99\f2\xa9i\xd3\xe27\x93\x82\xd0\u04d8\xba2\x8exl\x04\x93\x93W\x90\x9e\x9e\x86\xaee\xc0\r\xdd\x04^+\x03\xe7\u0724v\x84\xf8\xe8Tw6\x10\x13W\xb3\x8eS\xb4\x9c\xc9w\xbb5\xdd\xc4\xf1+\x067\x83J\x12#\x95\x95\x95(++CAA\xc1x]]]\xfb\xfa\xf5\xeb\xf7\xdes\xcf\u059f\x12B:\xdc\xd7{\xf0\xc1\xaf\x93{\xef\xbdW\xd4\xd4\xd4\xfa7\xbf\x0f\xe6~\xfc\xb1\xc5\xd3O?\x85S\xa7N\x91'\x9ex\u049d\xa9\xb3C\x87\x0e\u073as\xe7\xceM\xdd\xdd=\xab\x93\xc9\xe4\x82X,\x86\x81\x81ALOOA\xd7uLO'!\xc4\a2\xac\xbd\u028dLr\xe7\xd2\xffN\x16E\xde\xd1l\x1f\xe5\x02\xf5H\x02]_\xad\xb6y\u4302\xcb97y\u078d\xfd\x18\xce\x058\xe7\x90$\t\xaa\xaa\xa2\xa8\xa8\b\xd1h\x14\x91H\xd9XII\xc9\u19a6\xa6C\x1b7\xb6\x1c\xfd\u0527n\xdaE\b\xf1\xf0\xdfo\xbe\xf9+|\xfa\xd3\u007f\xe1\xdf\xec>\x98\xfb\xf1\xa7\x10\xb3\xa9\x18\x84\xe0\u05fe\xf8\xe2\x8b\x1b\xdb\xdb\xdb\xe7\uaeb6\xe2\u0295\x89\xf2s\xe7\xceM\x85\xc3\xe1\u56a6\x05{{\xcf#\x91H \x93I\xc308\f\xc3@&\x93\xf9\xe3\\x\xb9Y2!\x1e\xd31\xea\xea\xc1w\x17D\xed,;\xdf\x06f\u007f\x9fR{\xec\x9a\xd5\xf9i\xa9V\x18cP\xd5\x00**\xcaQ[[\v\u01a4\xe9`0\xd0Y]]=\xac\xaa\u02ae\xdbn\xdbrv\u035a\xb5\xbf\xca\u05d5\xb9k\xd7/q\xcb-\x9f\xf1on\x1f\xcc\xfd\xf8S\x8c\x8b\x17\x87\x10\x8d\xd6`p\xb0\x8f\xd4\xd6~B\xe4\x1c\xfb\xab\x00\x94\xec\u077b7\xd9\xdb\xdb3\xaf\xaf\xaf\xaf\xee\u0295\xc9\x06Bp\xfd\xc8H\x8c\xc6b#)JiEQQ\u046a\u02d7/c``\x10\x13\x13\x13\u0434\f4M\x83\xae\x1b0\f\x03\x9a\xa6\x9b<\xb7\xdbf\xe0Cj\x11\xbf\x9a\x89\x96\x99\a\x93\x19\xf3D\xb3\t\xf2l\xb9\xbdG\xcbm6\xfa0f\xd3%\xc4j\xa42m\x87\u0740\x9d}FB!\u02e6R\xc56\xb7b\x8cZ\xe0mf\u07a5\xa5%\xa8\xad\xadE0\x18\ucaac\xac\xec\f\x04\x82GC\xa1`\xe7\xbcy\u05cc\xb6\xb4l8\x1f\x8d\xd6^$\x84$\xec\xabvv\x9e!\xf3\xe6\xcd\x17\x00\xb0c\xc7S\u063cy3\xe6\u0319\xeb\xdf\xd0>\x98\xfb\xf1\xa7\x1c==\x9dhj\x9a\a!\x04v\xee\xfc9\x89\xc5b\xec\xc9'\x9f\x16\u01cf\x1f7\xf2\x03\xa6\xa8\xb0\xeeK\xbd\xa3\xe3T\xb8\xaf\xaf\u007fN[[[@Q\xe4\u0159Lf\xe5\u0673g\xb5\xe9\xe9diII\xf1\xba\x8b\x17/\x97\x0e\f\f`||\x1c\xba\xae!\x93\u0450L\x9a\xfe/6\xd8Sk B~\x80\xcf\xef\xed2\xc3\xfb\u071e=*\x04r\x8b\xb7\xb2,\x83Rj6\xf5\xe4\\U\x96e(\xb2\x9c\x05W\x0f\xc7M\x88w,\x9b\x95=\xeb\xba\x0e\u039d\xe9M\xf6\xefp\xceA)\x81$IP\x14\x15\xb2,\x811\x06J\x19dYBqq\xb1\x88F\xa3\xa4\xa4\xa48\x1d\x8f\xc7\x0f\x8c\x8d\x8d\x9fkhh\b44\u05031\xe98\xe7\xbcm\xf5\xea\x1b\x86W\xaf^;F\b\x19\xcd}\xcf\xf7\xddw\xaf\xb4b\xc5r\xb1l\xd92\xbed\xc9R\xf1\xfa\xeb\xff\x83M\x9b6\xfb7\xb0\x0f\xe6~\xf8q\xb5\fW\xe0\u0529\xf7iOO/y\xfb\xed}(,\f\xd3D\xe2\n}\xfc\xf1\xffH\xff\x86\xdf\v\x02\x10\xa9\u0514|\xe4\xc8\xe1\u04b6\xb6cJEE\xf9\xc6\u04e7;\x16\x8d\x8c\u0116\x8d\x8c\x8c.\x1e\x1a\x1a\n'\x12\xe3\xd40\xcc\x06\x97t:\x8d\xa9\xa9)LM%a\xaa\r\t4M\x87\xa6i\xf9\x93k\x80\u0232\fIbfc\x90p\x18sU\r\xa0\xa8\xa8\x10\x81@\x00\x92$\x81s\x81d2\t\x00P\x14\x05\xc1`\x00\x92$\x9bEXY\x02!$I\b\x9d,..DAA\x01\x14EE \xa0BUU(\x8a\n\xc6X\xf6\x89UU\xa5\xc1`\x80^\xb80\xb4\xef\xfc\xf9\xf3\xa7\xc2\xe10K\xa7\u04d9\xea\xea\xea\xe6`0T\xdc\xdf\xdfwZQ\x14c\xee\u0739\xa4\xbe\xbe\x1e\xc5\xc5E\b\x85B2\x80\xc1c\xc7\xda\xf7LNN&\u05acY%777\x19\r\r\r\xf1H\xa4j\n\xf6\xdc\rB\x92\xb9\xeb~\xfb\xf6\x87\x95T*i\xd4\xd7\u05cbU\xabV\x8a\xa5KW\xf8\xdap\x1f\xcc\xfd\xf0\xe3\u00cb\xae\xae3\u063d\xfb\xd7\u0636\xedK\xbf\xf1\xb1\xd3\xd3\x13U\x87\x0e\x1d^\xb7\u007f\xff\x81\x8at:\xb5H\b\\\xdf\xdd\u074dX,\x16\xe6\\\xd4%\x12\t#\x95JrEQKB\xa1\x90\xb5A8\x14\rc\fB\b$\x12\t=\x9dNO\xaa\xaaJM\xe0UH(\x14\x82,+\xa3\x15\x15\x91X}}=\"\x91\x88$\x84\xb8\xd4\xd9\xd9\xf9v:\x9d\x89777K\xcd\xcdM(..\x86$1Z\\\\\"\x15\x16\x16\xbe;22z|\xf5\xea\x1b\fYV\xd9\aY\x8b\x84\x90\xe9<\x9b\x98G\xfe\xf9\xdb\xc4\x0f\u007f\xf8\"\u05ad[\x87\xba\xba\x06\xff\xa6\xf2\xc1\xdc\x0f?>>\xd1\xde\xfe\x1e\x1e}\xf4\x9f\xf1\uaaef}\x90\x93@\xf9\x89\x13\xc7n>r\xa4-}\xe6\xcc\x19\xbd\xb2\xb2\xe2\x9a\xf2\xf2\xc8\n\xceE\x88s\xce3\x99\x8c\xb0\xb2c\x99\x10\x92\xec\xed=\xff\xf6\x85\v\x17\x06\xeb\xea\xeaX]]\x1d\xa9\xae\x8e\xb2\x86\x86\x06\xb2h\u0452vB\xc8\u064f\xe3\xe71<<\x88\xeaj_&\xe8\x87\x1f~\xfc\x81\xc7\xd0\xd0\xc0\xc7\xf2u\xdd\u007f\xff\xdfbp\xb0\xdf\xff\x03\xf9\xf1\xa1\xc7\xff\x03 \x99\rH\xa6\x0e6\x92\x00\x00\x00\x00IEND\xaeB`\x82")
+
+// dashboardDockerfile is the Dockerfile required to build an dashboard container
+// to aggregate various private network services under one easily accessible page.
+var dashboardDockerfile = `
+FROM mhart/alpine-node:latest
+
+RUN \
+ npm install connect serve-static && \
+ \
+ echo 'var connect = require("connect");' > server.js && \
+ echo 'var serveStatic = require("serve-static");' >> server.js && \
+ echo 'connect().use(serveStatic("/dashboard")).listen(80, function(){' >> server.js && \
+ echo ' console.log("Server running on 80...");' >> server.js && \
+ echo '});' >> server.js
+
+ADD {{.Network}}.json /dashboard/{{.Network}}.json
+ADD {{.Network}}-cpp.json /dashboard/{{.Network}}-cpp.json
+ADD {{.Network}}-harmony.json /dashboard/{{.Network}}-harmony.json
+ADD {{.Network}}-parity.json /dashboard/{{.Network}}-parity.json
+ADD {{.Network}}-python.json /dashboard/{{.Network}}-python.json
+ADD index.html /dashboard/index.html
+ADD puppeth.png /dashboard/puppeth.png
+
+EXPOSE 80
+
+CMD ["node", "/server.js"]
+`
+
+// dashboardComposefile is the docker-compose.yml file required to deploy and
+// maintain an service aggregating dashboard.
+var dashboardComposefile = `
+version: '2'
+services:
+ dashboard:
+ build: .
+ image: {{.Network}}/dashboard{{if not .VHost}}
+ ports:
+ - "{{.Port}}:80"{{end}}
+ environment:
+ - ETHSTATS_PAGE={{.EthstatsPage}}
+ - EXPLORER_PAGE={{.ExplorerPage}}
+ - WALLET_PAGE={{.WalletPage}}
+ - FAUCET_PAGE={{.FaucetPage}}{{if .VHost}}
+ - VIRTUAL_HOST={{.VHost}}{{end}}
+ logging:
+ driver: "json-file"
+ options:
+ max-size: "1m"
+ max-file: "10"
+ restart: always
+`
+
+// deployDashboard deploys a new dashboard container to a remote machine via SSH,
+// docker and docker-compose. If an instance with the specified network name
+// already exists there, it will be overwritten!
+func deployDashboard(client *sshClient, network string, conf *config, config *dashboardInfos, nocache bool) ([]byte, error) {
+ // Generate the content to upload to the server
+ workdir := fmt.Sprintf("%d", rand.Int63())
+ files := make(map[string][]byte)
+
+ dockerfile := new(bytes.Buffer)
+ template.Must(template.New("").Parse(dashboardDockerfile)).Execute(dockerfile, map[string]interface{}{
+ "Network": network,
+ })
+ files[filepath.Join(workdir, "Dockerfile")] = dockerfile.Bytes()
+
+ composefile := new(bytes.Buffer)
+ template.Must(template.New("").Parse(dashboardComposefile)).Execute(composefile, map[string]interface{}{
+ "Network": network,
+ "Port": config.port,
+ "VHost": config.host,
+ "EthstatsPage": config.ethstats,
+ "ExplorerPage": config.explorer,
+ "WalletPage": config.wallet,
+ "FaucetPage": config.faucet,
+ })
+ files[filepath.Join(workdir, "docker-compose.yaml")] = composefile.Bytes()
+
+ statsLogin := fmt.Sprintf("yournode:%s", conf.ethstats)
+ if !config.trusted {
+ statsLogin = ""
+ }
+ indexfile := new(bytes.Buffer)
+ bootCpp := make([]string, len(conf.bootnodes))
+ for i, boot := range conf.bootnodes {
+ bootCpp[i] = "required:" + strings.TrimPrefix(boot, "enode://")
+ }
+ bootHarmony := make([]string, len(conf.bootnodes))
+ for i, boot := range conf.bootnodes {
+ bootHarmony[i] = fmt.Sprintf("-Dpeer.active.%d.url=%s", i, boot)
+ }
+ bootPython := make([]string, len(conf.bootnodes))
+ for i, boot := range conf.bootnodes {
+ bootPython[i] = "'" + boot + "'"
+ }
+ template.Must(template.New("").Parse(dashboardContent)).Execute(indexfile, map[string]interface{}{
+ "Network": network,
+ "NetworkID": conf.Genesis.Config.ChainID,
+ "NetworkTitle": strings.Title(network),
+ "EthstatsPage": config.ethstats,
+ "ExplorerPage": config.explorer,
+ "WalletPage": config.wallet,
+ "FaucetPage": config.faucet,
+ "GethGenesis": network + ".json",
+ "Bootnodes": conf.bootnodes,
+ "BootnodesFlat": strings.Join(conf.bootnodes, ","),
+ "Ethstats": statsLogin,
+ "Ethash": conf.Genesis.Config.Ethash != nil,
+ "CppGenesis": network + "-cpp.json",
+ "CppBootnodes": strings.Join(bootCpp, " "),
+ "HarmonyGenesis": network + "-harmony.json",
+ "HarmonyBootnodes": strings.Join(bootHarmony, " "),
+ "ParityGenesis": network + "-parity.json",
+ "PythonGenesis": network + "-python.json",
+ "PythonBootnodes": strings.Join(bootPython, ","),
+ "Homestead": conf.Genesis.Config.HomesteadBlock,
+ "Tangerine": conf.Genesis.Config.EIP150Block,
+ "Spurious": conf.Genesis.Config.EIP155Block,
+ "Byzantium": conf.Genesis.Config.ByzantiumBlock,
+ "Constantinople": conf.Genesis.Config.ConstantinopleBlock,
+ "ConstantinopleFix": conf.Genesis.Config.PetersburgBlock,
+ })
+ files[filepath.Join(workdir, "index.html")] = indexfile.Bytes()
+
+ // Marshal the genesis spec files for go-ethereum and all the other clients
+ genesis, _ := conf.Genesis.MarshalJSON()
+ files[filepath.Join(workdir, network+".json")] = genesis
+
+ if conf.Genesis.Config.Ethash != nil {
+ cppSpec, err := newAlethGenesisSpec(network, conf.Genesis)
+ if err != nil {
+ return nil, err
+ }
+ cppSpecJSON, _ := json.Marshal(cppSpec)
+ files[filepath.Join(workdir, network+"-cpp.json")] = cppSpecJSON
+
+ harmonySpecJSON, _ := conf.Genesis.MarshalJSON()
+ files[filepath.Join(workdir, network+"-harmony.json")] = harmonySpecJSON
+
+ paritySpec, err := newParityChainSpec(network, conf.Genesis, conf.bootnodes)
+ if err != nil {
+ return nil, err
+ }
+ paritySpecJSON, _ := json.Marshal(paritySpec)
+ files[filepath.Join(workdir, network+"-parity.json")] = paritySpecJSON
+
+ pyethSpec, err := newPyEthereumGenesisSpec(network, conf.Genesis)
+ if err != nil {
+ return nil, err
+ }
+ pyethSpecJSON, _ := json.Marshal(pyethSpec)
+ files[filepath.Join(workdir, network+"-python.json")] = pyethSpecJSON
+ } else {
+ for _, client := range []string{"cpp", "harmony", "parity", "python"} {
+ files[filepath.Join(workdir, network+"-"+client+".json")] = []byte{}
+ }
+ }
+ files[filepath.Join(workdir, "puppeth.png")] = dashboardMascot
+
+ // Upload the deployment files to the remote server (and clean up afterwards)
+ if out, err := client.Upload(files); err != nil {
+ return out, err
+ }
+ defer client.Run("rm -rf " + workdir)
+
+ // Build and deploy the dashboard service
+ if nocache {
+ return nil, client.Stream(fmt.Sprintf("cd %s && docker-compose -p %s build --pull --no-cache && docker-compose -p %s up -d --force-recreate --timeout 60", workdir, network, network))
+ }
+ return nil, client.Stream(fmt.Sprintf("cd %s && docker-compose -p %s up -d --build --force-recreate --timeout 60", workdir, network))
+}
+
+// dashboardInfos is returned from a dashboard status check to allow reporting
+// various configuration parameters.
+type dashboardInfos struct {
+ host string
+ port int
+ trusted bool
+
+ ethstats string
+ explorer string
+ wallet string
+ faucet string
+}
+
+// Report converts the typed struct into a plain string->string map, containing
+// most - but not all - fields for reporting to the user.
+func (info *dashboardInfos) Report() map[string]string {
+ return map[string]string{
+ "Website address": info.host,
+ "Website listener port": strconv.Itoa(info.port),
+ "Ethstats service": info.ethstats,
+ "Explorer service": info.explorer,
+ "Wallet service": info.wallet,
+ "Faucet service": info.faucet,
+ }
+}
+
+// checkDashboard does a health-check against a dashboard container to verify if
+// it's running, and if yes, gathering a collection of useful infos about it.
+func checkDashboard(client *sshClient, network string) (*dashboardInfos, error) {
+ // Inspect a possible ethstats container on the host
+ infos, err := inspectContainer(client, fmt.Sprintf("%s_dashboard_1", network))
+ if err != nil {
+ return nil, err
+ }
+ if !infos.running {
+ return nil, ErrServiceOffline
+ }
+ // Resolve the port from the host, or the reverse proxy
+ port := infos.portmap["80/tcp"]
+ if port == 0 {
+ if proxy, _ := checkNginx(client, network); proxy != nil {
+ port = proxy.port
+ }
+ }
+ if port == 0 {
+ return nil, ErrNotExposed
+ }
+ // Resolve the host from the reverse-proxy and configure the connection string
+ host := infos.envvars["VIRTUAL_HOST"]
+ if host == "" {
+ host = client.server
+ }
+ // Run a sanity check to see if the port is reachable
+ if err = checkPort(host, port); err != nil {
+ log.Warn("Dashboard service seems unreachable", "server", host, "port", port, "err", err)
+ }
+ // Container available, assemble and return the useful infos
+ return &dashboardInfos{
+ host: host,
+ port: port,
+ ethstats: infos.envvars["ETHSTATS_PAGE"],
+ explorer: infos.envvars["EXPLORER_PAGE"],
+ wallet: infos.envvars["WALLET_PAGE"],
+ faucet: infos.envvars["FAUCET_PAGE"],
+ }, nil
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/puppeth/module_ethstats.go b/vendor/github.com/ethereum/go-ethereum/cmd/puppeth/module_ethstats.go
new file mode 100644
index 00000000..58ecb839
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/cmd/puppeth/module_ethstats.go
@@ -0,0 +1,176 @@
+// Copyright 2017 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// go-ethereum is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with go-ethereum. If not, see .
+
+package main
+
+import (
+ "bytes"
+ "fmt"
+ "math/rand"
+ "path/filepath"
+ "strconv"
+ "strings"
+ "text/template"
+
+ "github.com/ethereum/go-ethereum/log"
+)
+
+// ethstatsDockerfile is the Dockerfile required to build an ethstats backend
+// and associated monitoring site.
+var ethstatsDockerfile = `
+FROM puppeth/ethstats:latest
+
+RUN echo 'module.exports = {trusted: [{{.Trusted}}], banned: [{{.Banned}}], reserved: ["yournode"]};' > lib/utils/config.js
+`
+
+// ethstatsComposefile is the docker-compose.yml file required to deploy and
+// maintain an ethstats monitoring site.
+var ethstatsComposefile = `
+version: '2'
+services:
+ ethstats:
+ build: .
+ image: {{.Network}}/ethstats
+ container_name: {{.Network}}_ethstats_1{{if not .VHost}}
+ ports:
+ - "{{.Port}}:3000"{{end}}
+ environment:
+ - WS_SECRET={{.Secret}}{{if .VHost}}
+ - VIRTUAL_HOST={{.VHost}}{{end}}{{if .Banned}}
+ - BANNED={{.Banned}}{{end}}
+ logging:
+ driver: "json-file"
+ options:
+ max-size: "1m"
+ max-file: "10"
+ restart: always
+`
+
+// deployEthstats deploys a new ethstats container to a remote machine via SSH,
+// docker and docker-compose. If an instance with the specified network name
+// already exists there, it will be overwritten!
+func deployEthstats(client *sshClient, network string, port int, secret string, vhost string, trusted []string, banned []string, nocache bool) ([]byte, error) {
+ // Generate the content to upload to the server
+ workdir := fmt.Sprintf("%d", rand.Int63())
+ files := make(map[string][]byte)
+
+ trustedLabels := make([]string, len(trusted))
+ for i, address := range trusted {
+ trustedLabels[i] = fmt.Sprintf("\"%s\"", address)
+ }
+ bannedLabels := make([]string, len(banned))
+ for i, address := range banned {
+ bannedLabels[i] = fmt.Sprintf("\"%s\"", address)
+ }
+
+ dockerfile := new(bytes.Buffer)
+ template.Must(template.New("").Parse(ethstatsDockerfile)).Execute(dockerfile, map[string]interface{}{
+ "Trusted": strings.Join(trustedLabels, ", "),
+ "Banned": strings.Join(bannedLabels, ", "),
+ })
+ files[filepath.Join(workdir, "Dockerfile")] = dockerfile.Bytes()
+
+ composefile := new(bytes.Buffer)
+ template.Must(template.New("").Parse(ethstatsComposefile)).Execute(composefile, map[string]interface{}{
+ "Network": network,
+ "Port": port,
+ "Secret": secret,
+ "VHost": vhost,
+ "Banned": strings.Join(banned, ","),
+ })
+ files[filepath.Join(workdir, "docker-compose.yaml")] = composefile.Bytes()
+
+ // Upload the deployment files to the remote server (and clean up afterwards)
+ if out, err := client.Upload(files); err != nil {
+ return out, err
+ }
+ defer client.Run("rm -rf " + workdir)
+
+ // Build and deploy the ethstats service
+ if nocache {
+ return nil, client.Stream(fmt.Sprintf("cd %s && docker-compose -p %s build --pull --no-cache && docker-compose -p %s up -d --force-recreate --timeout 60", workdir, network, network))
+ }
+ return nil, client.Stream(fmt.Sprintf("cd %s && docker-compose -p %s up -d --build --force-recreate --timeout 60", workdir, network))
+}
+
+// ethstatsInfos is returned from an ethstats status check to allow reporting
+// various configuration parameters.
+type ethstatsInfos struct {
+ host string
+ port int
+ secret string
+ config string
+ banned []string
+}
+
+// Report converts the typed struct into a plain string->string map, containing
+// most - but not all - fields for reporting to the user.
+func (info *ethstatsInfos) Report() map[string]string {
+ return map[string]string{
+ "Website address": info.host,
+ "Website listener port": strconv.Itoa(info.port),
+ "Login secret": info.secret,
+ "Banned addresses": strings.Join(info.banned, "\n"),
+ }
+}
+
+// checkEthstats does a health-check against an ethstats server to verify whether
+// it's running, and if yes, gathering a collection of useful infos about it.
+func checkEthstats(client *sshClient, network string) (*ethstatsInfos, error) {
+ // Inspect a possible ethstats container on the host
+ infos, err := inspectContainer(client, fmt.Sprintf("%s_ethstats_1", network))
+ if err != nil {
+ return nil, err
+ }
+ if !infos.running {
+ return nil, ErrServiceOffline
+ }
+ // Resolve the port from the host, or the reverse proxy
+ port := infos.portmap["3000/tcp"]
+ if port == 0 {
+ if proxy, _ := checkNginx(client, network); proxy != nil {
+ port = proxy.port
+ }
+ }
+ if port == 0 {
+ return nil, ErrNotExposed
+ }
+ // Resolve the host from the reverse-proxy and configure the connection string
+ host := infos.envvars["VIRTUAL_HOST"]
+ if host == "" {
+ host = client.server
+ }
+ secret := infos.envvars["WS_SECRET"]
+ config := fmt.Sprintf("%s@%s", secret, host)
+ if port != 80 && port != 443 {
+ config += fmt.Sprintf(":%d", port)
+ }
+ // Retrieve the IP blacklist
+ banned := strings.Split(infos.envvars["BANNED"], ",")
+
+ // Run a sanity check to see if the port is reachable
+ if err = checkPort(host, port); err != nil {
+ log.Warn("Ethstats service seems unreachable", "server", host, "port", port, "err", err)
+ }
+ // Container available, assemble and return the useful infos
+ return ðstatsInfos{
+ host: host,
+ port: port,
+ secret: secret,
+ config: config,
+ banned: banned,
+ }, nil
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/puppeth/module_explorer.go b/vendor/github.com/ethereum/go-ethereum/cmd/puppeth/module_explorer.go
new file mode 100644
index 00000000..e465fa04
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/cmd/puppeth/module_explorer.go
@@ -0,0 +1,212 @@
+// Copyright 2017 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// go-ethereum is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with go-ethereum. If not, see .
+
+package main
+
+import (
+ "bytes"
+ "fmt"
+ "html/template"
+ "math/rand"
+ "path/filepath"
+ "strconv"
+ "strings"
+
+ "github.com/ethereum/go-ethereum/log"
+)
+
+// explorerDockerfile is the Dockerfile required to run a block explorer.
+var explorerDockerfile = `
+FROM puppeth/explorer:latest
+
+ADD ethstats.json /ethstats.json
+ADD chain.json /chain.json
+
+RUN \
+ echo '(cd ../eth-net-intelligence-api && pm2 start /ethstats.json)' > explorer.sh && \
+ echo '(cd ../etherchain-light && npm start &)' >> explorer.sh && \
+ echo 'exec /parity/parity --chain=/chain.json --port={{.NodePort}} --tracing=on --fat-db=on --pruning=archive' >> explorer.sh
+
+ENTRYPOINT ["/bin/sh", "explorer.sh"]
+`
+
+// explorerEthstats is the configuration file for the ethstats javascript client.
+var explorerEthstats = `[
+ {
+ "name" : "node-app",
+ "script" : "app.js",
+ "log_date_format" : "YYYY-MM-DD HH:mm Z",
+ "merge_logs" : false,
+ "watch" : false,
+ "max_restarts" : 10,
+ "exec_interpreter" : "node",
+ "exec_mode" : "fork_mode",
+ "env":
+ {
+ "NODE_ENV" : "production",
+ "RPC_HOST" : "localhost",
+ "RPC_PORT" : "8545",
+ "LISTENING_PORT" : "{{.Port}}",
+ "INSTANCE_NAME" : "{{.Name}}",
+ "CONTACT_DETAILS" : "",
+ "WS_SERVER" : "{{.Host}}",
+ "WS_SECRET" : "{{.Secret}}",
+ "VERBOSITY" : 2
+ }
+ }
+]`
+
+// explorerComposefile is the docker-compose.yml file required to deploy and
+// maintain a block explorer.
+var explorerComposefile = `
+version: '2'
+services:
+ explorer:
+ build: .
+ image: {{.Network}}/explorer
+ container_name: {{.Network}}_explorer_1
+ ports:
+ - "{{.NodePort}}:{{.NodePort}}"
+ - "{{.NodePort}}:{{.NodePort}}/udp"{{if not .VHost}}
+ - "{{.WebPort}}:3000"{{end}}
+ volumes:
+ - {{.Datadir}}:/root/.local/share/io.parity.ethereum
+ environment:
+ - NODE_PORT={{.NodePort}}/tcp
+ - STATS={{.Ethstats}}{{if .VHost}}
+ - VIRTUAL_HOST={{.VHost}}
+ - VIRTUAL_PORT=3000{{end}}
+ logging:
+ driver: "json-file"
+ options:
+ max-size: "1m"
+ max-file: "10"
+ restart: always
+`
+
+// deployExplorer deploys a new block explorer container to a remote machine via
+// SSH, docker and docker-compose. If an instance with the specified network name
+// already exists there, it will be overwritten!
+func deployExplorer(client *sshClient, network string, chainspec []byte, config *explorerInfos, nocache bool) ([]byte, error) {
+ // Generate the content to upload to the server
+ workdir := fmt.Sprintf("%d", rand.Int63())
+ files := make(map[string][]byte)
+
+ dockerfile := new(bytes.Buffer)
+ template.Must(template.New("").Parse(explorerDockerfile)).Execute(dockerfile, map[string]interface{}{
+ "NodePort": config.nodePort,
+ })
+ files[filepath.Join(workdir, "Dockerfile")] = dockerfile.Bytes()
+
+ ethstats := new(bytes.Buffer)
+ template.Must(template.New("").Parse(explorerEthstats)).Execute(ethstats, map[string]interface{}{
+ "Port": config.nodePort,
+ "Name": config.ethstats[:strings.Index(config.ethstats, ":")],
+ "Secret": config.ethstats[strings.Index(config.ethstats, ":")+1 : strings.Index(config.ethstats, "@")],
+ "Host": config.ethstats[strings.Index(config.ethstats, "@")+1:],
+ })
+ files[filepath.Join(workdir, "ethstats.json")] = ethstats.Bytes()
+
+ composefile := new(bytes.Buffer)
+ template.Must(template.New("").Parse(explorerComposefile)).Execute(composefile, map[string]interface{}{
+ "Datadir": config.datadir,
+ "Network": network,
+ "NodePort": config.nodePort,
+ "VHost": config.webHost,
+ "WebPort": config.webPort,
+ "Ethstats": config.ethstats[:strings.Index(config.ethstats, ":")],
+ })
+ files[filepath.Join(workdir, "docker-compose.yaml")] = composefile.Bytes()
+
+ files[filepath.Join(workdir, "chain.json")] = chainspec
+
+ // Upload the deployment files to the remote server (and clean up afterwards)
+ if out, err := client.Upload(files); err != nil {
+ return out, err
+ }
+ defer client.Run("rm -rf " + workdir)
+
+ // Build and deploy the boot or seal node service
+ if nocache {
+ return nil, client.Stream(fmt.Sprintf("cd %s && docker-compose -p %s build --pull --no-cache && docker-compose -p %s up -d --force-recreate --timeout 60", workdir, network, network))
+ }
+ return nil, client.Stream(fmt.Sprintf("cd %s && docker-compose -p %s up -d --build --force-recreate --timeout 60", workdir, network))
+}
+
+// explorerInfos is returned from a block explorer status check to allow reporting
+// various configuration parameters.
+type explorerInfos struct {
+ datadir string
+ ethstats string
+ nodePort int
+ webHost string
+ webPort int
+}
+
+// Report converts the typed struct into a plain string->string map, containing
+// most - but not all - fields for reporting to the user.
+func (info *explorerInfos) Report() map[string]string {
+ report := map[string]string{
+ "Data directory": info.datadir,
+ "Node listener port ": strconv.Itoa(info.nodePort),
+ "Ethstats username": info.ethstats,
+ "Website address ": info.webHost,
+ "Website listener port ": strconv.Itoa(info.webPort),
+ }
+ return report
+}
+
+// checkExplorer does a health-check against a block explorer server to verify
+// whether it's running, and if yes, whether it's responsive.
+func checkExplorer(client *sshClient, network string) (*explorerInfos, error) {
+ // Inspect a possible block explorer container on the host
+ infos, err := inspectContainer(client, fmt.Sprintf("%s_explorer_1", network))
+ if err != nil {
+ return nil, err
+ }
+ if !infos.running {
+ return nil, ErrServiceOffline
+ }
+ // Resolve the port from the host, or the reverse proxy
+ webPort := infos.portmap["3000/tcp"]
+ if webPort == 0 {
+ if proxy, _ := checkNginx(client, network); proxy != nil {
+ webPort = proxy.port
+ }
+ }
+ if webPort == 0 {
+ return nil, ErrNotExposed
+ }
+ // Resolve the host from the reverse-proxy and the config values
+ host := infos.envvars["VIRTUAL_HOST"]
+ if host == "" {
+ host = client.server
+ }
+ // Run a sanity check to see if the devp2p is reachable
+ nodePort := infos.portmap[infos.envvars["NODE_PORT"]]
+ if err = checkPort(client.server, nodePort); err != nil {
+ log.Warn(fmt.Sprintf("Explorer devp2p port seems unreachable"), "server", client.server, "port", nodePort, "err", err)
+ }
+ // Assemble and return the useful infos
+ stats := &explorerInfos{
+ datadir: infos.volumes["/root/.local/share/io.parity.ethereum"],
+ nodePort: nodePort,
+ webHost: host,
+ webPort: webPort,
+ ethstats: infos.envvars["STATS"],
+ }
+ return stats, nil
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/puppeth/module_faucet.go b/vendor/github.com/ethereum/go-ethereum/cmd/puppeth/module_faucet.go
new file mode 100644
index 00000000..3a06bf3c
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/cmd/puppeth/module_faucet.go
@@ -0,0 +1,247 @@
+// Copyright 2017 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// go-ethereum is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with go-ethereum. If not, see .
+
+package main
+
+import (
+ "bytes"
+ "encoding/json"
+ "fmt"
+ "html/template"
+ "math/rand"
+ "path/filepath"
+ "strconv"
+ "strings"
+
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/log"
+)
+
+// faucetDockerfile is the Dockerfile required to build a faucet container to
+// grant crypto tokens based on GitHub authentications.
+var faucetDockerfile = `
+FROM ethereum/client-go:alltools-latest
+
+ADD genesis.json /genesis.json
+ADD account.json /account.json
+ADD account.pass /account.pass
+
+EXPOSE 8080 30303 30303/udp
+
+ENTRYPOINT [ \
+ "faucet", "--genesis", "/genesis.json", "--network", "{{.NetworkID}}", "--bootnodes", "{{.Bootnodes}}", "--ethstats", "{{.Ethstats}}", "--ethport", "{{.EthPort}}", \
+ "--faucet.name", "{{.FaucetName}}", "--faucet.amount", "{{.FaucetAmount}}", "--faucet.minutes", "{{.FaucetMinutes}}", "--faucet.tiers", "{{.FaucetTiers}}", \
+ "--account.json", "/account.json", "--account.pass", "/account.pass" \
+ {{if .CaptchaToken}}, "--captcha.token", "{{.CaptchaToken}}", "--captcha.secret", "{{.CaptchaSecret}}"{{end}}{{if .NoAuth}}, "--noauth"{{end}} \
+]`
+
+// faucetComposefile is the docker-compose.yml file required to deploy and maintain
+// a crypto faucet.
+var faucetComposefile = `
+version: '2'
+services:
+ faucet:
+ build: .
+ image: {{.Network}}/faucet
+ container_name: {{.Network}}_faucet_1
+ ports:
+ - "{{.EthPort}}:{{.EthPort}}"
+ - "{{.EthPort}}:{{.EthPort}}/udp"{{if not .VHost}}
+ - "{{.ApiPort}}:8080"{{end}}
+ volumes:
+ - {{.Datadir}}:/root/.faucet
+ environment:
+ - ETH_PORT={{.EthPort}}
+ - ETH_NAME={{.EthName}}
+ - FAUCET_AMOUNT={{.FaucetAmount}}
+ - FAUCET_MINUTES={{.FaucetMinutes}}
+ - FAUCET_TIERS={{.FaucetTiers}}
+ - CAPTCHA_TOKEN={{.CaptchaToken}}
+ - CAPTCHA_SECRET={{.CaptchaSecret}}
+ - NO_AUTH={{.NoAuth}}{{if .VHost}}
+ - VIRTUAL_HOST={{.VHost}}
+ - VIRTUAL_PORT=8080{{end}}
+ logging:
+ driver: "json-file"
+ options:
+ max-size: "1m"
+ max-file: "10"
+ restart: always
+`
+
+// deployFaucet deploys a new faucet container to a remote machine via SSH,
+// docker and docker-compose. If an instance with the specified network name
+// already exists there, it will be overwritten!
+func deployFaucet(client *sshClient, network string, bootnodes []string, config *faucetInfos, nocache bool) ([]byte, error) {
+ // Generate the content to upload to the server
+ workdir := fmt.Sprintf("%d", rand.Int63())
+ files := make(map[string][]byte)
+
+ dockerfile := new(bytes.Buffer)
+ template.Must(template.New("").Parse(faucetDockerfile)).Execute(dockerfile, map[string]interface{}{
+ "NetworkID": config.node.network,
+ "Bootnodes": strings.Join(bootnodes, ","),
+ "Ethstats": config.node.ethstats,
+ "EthPort": config.node.port,
+ "CaptchaToken": config.captchaToken,
+ "CaptchaSecret": config.captchaSecret,
+ "FaucetName": strings.Title(network),
+ "FaucetAmount": config.amount,
+ "FaucetMinutes": config.minutes,
+ "FaucetTiers": config.tiers,
+ "NoAuth": config.noauth,
+ })
+ files[filepath.Join(workdir, "Dockerfile")] = dockerfile.Bytes()
+
+ composefile := new(bytes.Buffer)
+ template.Must(template.New("").Parse(faucetComposefile)).Execute(composefile, map[string]interface{}{
+ "Network": network,
+ "Datadir": config.node.datadir,
+ "VHost": config.host,
+ "ApiPort": config.port,
+ "EthPort": config.node.port,
+ "EthName": config.node.ethstats[:strings.Index(config.node.ethstats, ":")],
+ "CaptchaToken": config.captchaToken,
+ "CaptchaSecret": config.captchaSecret,
+ "FaucetAmount": config.amount,
+ "FaucetMinutes": config.minutes,
+ "FaucetTiers": config.tiers,
+ "NoAuth": config.noauth,
+ })
+ files[filepath.Join(workdir, "docker-compose.yaml")] = composefile.Bytes()
+
+ files[filepath.Join(workdir, "genesis.json")] = config.node.genesis
+ files[filepath.Join(workdir, "account.json")] = []byte(config.node.keyJSON)
+ files[filepath.Join(workdir, "account.pass")] = []byte(config.node.keyPass)
+
+ // Upload the deployment files to the remote server (and clean up afterwards)
+ if out, err := client.Upload(files); err != nil {
+ return out, err
+ }
+ defer client.Run("rm -rf " + workdir)
+
+ // Build and deploy the faucet service
+ if nocache {
+ return nil, client.Stream(fmt.Sprintf("cd %s && docker-compose -p %s build --pull --no-cache && docker-compose -p %s up -d --force-recreate --timeout 60", workdir, network, network))
+ }
+ return nil, client.Stream(fmt.Sprintf("cd %s && docker-compose -p %s up -d --build --force-recreate --timeout 60", workdir, network))
+}
+
+// faucetInfos is returned from a faucet status check to allow reporting various
+// configuration parameters.
+type faucetInfos struct {
+ node *nodeInfos
+ host string
+ port int
+ amount int
+ minutes int
+ tiers int
+ noauth bool
+ captchaToken string
+ captchaSecret string
+}
+
+// Report converts the typed struct into a plain string->string map, containing
+// most - but not all - fields for reporting to the user.
+func (info *faucetInfos) Report() map[string]string {
+ report := map[string]string{
+ "Website address": info.host,
+ "Website listener port": strconv.Itoa(info.port),
+ "Ethereum listener port": strconv.Itoa(info.node.port),
+ "Funding amount (base tier)": fmt.Sprintf("%d Ethers", info.amount),
+ "Funding cooldown (base tier)": fmt.Sprintf("%d mins", info.minutes),
+ "Funding tiers": strconv.Itoa(info.tiers),
+ "Captha protection": fmt.Sprintf("%v", info.captchaToken != ""),
+ "Ethstats username": info.node.ethstats,
+ }
+ if info.noauth {
+ report["Debug mode (no auth)"] = "enabled"
+ }
+ if info.node.keyJSON != "" {
+ var key struct {
+ Address string `json:"address"`
+ }
+ if err := json.Unmarshal([]byte(info.node.keyJSON), &key); err == nil {
+ report["Funding account"] = common.HexToAddress(key.Address).Hex()
+ } else {
+ log.Error("Failed to retrieve signer address", "err", err)
+ }
+ }
+ return report
+}
+
+// checkFaucet does a health-check against a faucet server to verify whether
+// it's running, and if yes, gathering a collection of useful infos about it.
+func checkFaucet(client *sshClient, network string) (*faucetInfos, error) {
+ // Inspect a possible faucet container on the host
+ infos, err := inspectContainer(client, fmt.Sprintf("%s_faucet_1", network))
+ if err != nil {
+ return nil, err
+ }
+ if !infos.running {
+ return nil, ErrServiceOffline
+ }
+ // Resolve the port from the host, or the reverse proxy
+ port := infos.portmap["8080/tcp"]
+ if port == 0 {
+ if proxy, _ := checkNginx(client, network); proxy != nil {
+ port = proxy.port
+ }
+ }
+ if port == 0 {
+ return nil, ErrNotExposed
+ }
+ // Resolve the host from the reverse-proxy and the config values
+ host := infos.envvars["VIRTUAL_HOST"]
+ if host == "" {
+ host = client.server
+ }
+ amount, _ := strconv.Atoi(infos.envvars["FAUCET_AMOUNT"])
+ minutes, _ := strconv.Atoi(infos.envvars["FAUCET_MINUTES"])
+ tiers, _ := strconv.Atoi(infos.envvars["FAUCET_TIERS"])
+
+ // Retrieve the funding account informations
+ var out []byte
+ keyJSON, keyPass := "", ""
+ if out, err = client.Run(fmt.Sprintf("docker exec %s_faucet_1 cat /account.json", network)); err == nil {
+ keyJSON = string(bytes.TrimSpace(out))
+ }
+ if out, err = client.Run(fmt.Sprintf("docker exec %s_faucet_1 cat /account.pass", network)); err == nil {
+ keyPass = string(bytes.TrimSpace(out))
+ }
+ // Run a sanity check to see if the port is reachable
+ if err = checkPort(host, port); err != nil {
+ log.Warn("Faucet service seems unreachable", "server", host, "port", port, "err", err)
+ }
+ // Container available, assemble and return the useful infos
+ return &faucetInfos{
+ node: &nodeInfos{
+ datadir: infos.volumes["/root/.faucet"],
+ port: infos.portmap[infos.envvars["ETH_PORT"]+"/tcp"],
+ ethstats: infos.envvars["ETH_NAME"],
+ keyJSON: keyJSON,
+ keyPass: keyPass,
+ },
+ host: host,
+ port: port,
+ amount: amount,
+ minutes: minutes,
+ tiers: tiers,
+ captchaToken: infos.envvars["CAPTCHA_TOKEN"],
+ captchaSecret: infos.envvars["CAPTCHA_SECRET"],
+ noauth: infos.envvars["NO_AUTH"] == "true",
+ }, nil
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/puppeth/module_nginx.go b/vendor/github.com/ethereum/go-ethereum/cmd/puppeth/module_nginx.go
new file mode 100644
index 00000000..1b1ae61f
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/cmd/puppeth/module_nginx.go
@@ -0,0 +1,119 @@
+// Copyright 2017 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// go-ethereum is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with go-ethereum. If not, see .
+
+package main
+
+import (
+ "bytes"
+ "fmt"
+ "html/template"
+ "math/rand"
+ "path/filepath"
+ "strconv"
+
+ "github.com/ethereum/go-ethereum/log"
+)
+
+// nginxDockerfile is theis the Dockerfile required to build an nginx reverse-
+// proxy.
+var nginxDockerfile = `FROM jwilder/nginx-proxy`
+
+// nginxComposefile is the docker-compose.yml file required to deploy and maintain
+// an nginx reverse-proxy. The proxy is responsible for exposing one or more HTTP
+// services running on a single host.
+var nginxComposefile = `
+version: '2'
+services:
+ nginx:
+ build: .
+ image: {{.Network}}/nginx
+ container_name: {{.Network}}_nginx_1
+ ports:
+ - "{{.Port}}:80"
+ volumes:
+ - /var/run/docker.sock:/tmp/docker.sock:ro
+ logging:
+ driver: "json-file"
+ options:
+ max-size: "1m"
+ max-file: "10"
+ restart: always
+`
+
+// deployNginx deploys a new nginx reverse-proxy container to expose one or more
+// HTTP services running on a single host. If an instance with the specified
+// network name already exists there, it will be overwritten!
+func deployNginx(client *sshClient, network string, port int, nocache bool) ([]byte, error) {
+ log.Info("Deploying nginx reverse-proxy", "server", client.server, "port", port)
+
+ // Generate the content to upload to the server
+ workdir := fmt.Sprintf("%d", rand.Int63())
+ files := make(map[string][]byte)
+
+ dockerfile := new(bytes.Buffer)
+ template.Must(template.New("").Parse(nginxDockerfile)).Execute(dockerfile, nil)
+ files[filepath.Join(workdir, "Dockerfile")] = dockerfile.Bytes()
+
+ composefile := new(bytes.Buffer)
+ template.Must(template.New("").Parse(nginxComposefile)).Execute(composefile, map[string]interface{}{
+ "Network": network,
+ "Port": port,
+ })
+ files[filepath.Join(workdir, "docker-compose.yaml")] = composefile.Bytes()
+
+ // Upload the deployment files to the remote server (and clean up afterwards)
+ if out, err := client.Upload(files); err != nil {
+ return out, err
+ }
+ defer client.Run("rm -rf " + workdir)
+
+ // Build and deploy the reverse-proxy service
+ if nocache {
+ return nil, client.Stream(fmt.Sprintf("cd %s && docker-compose -p %s build --pull --no-cache && docker-compose -p %s up -d --force-recreate --timeout 60", workdir, network, network))
+ }
+ return nil, client.Stream(fmt.Sprintf("cd %s && docker-compose -p %s up -d --build --force-recreate --timeout 60", workdir, network))
+}
+
+// nginxInfos is returned from an nginx reverse-proxy status check to allow
+// reporting various configuration parameters.
+type nginxInfos struct {
+ port int
+}
+
+// Report converts the typed struct into a plain string->string map, containing
+// most - but not all - fields for reporting to the user.
+func (info *nginxInfos) Report() map[string]string {
+ return map[string]string{
+ "Shared listener port": strconv.Itoa(info.port),
+ }
+}
+
+// checkNginx does a health-check against an nginx reverse-proxy to verify whether
+// it's running, and if yes, gathering a collection of useful infos about it.
+func checkNginx(client *sshClient, network string) (*nginxInfos, error) {
+ // Inspect a possible nginx container on the host
+ infos, err := inspectContainer(client, fmt.Sprintf("%s_nginx_1", network))
+ if err != nil {
+ return nil, err
+ }
+ if !infos.running {
+ return nil, ErrServiceOffline
+ }
+ // Container available, assemble and return the useful infos
+ return &nginxInfos{
+ port: infos.portmap["80/tcp"],
+ }, nil
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/puppeth/module_node.go b/vendor/github.com/ethereum/go-ethereum/cmd/puppeth/module_node.go
new file mode 100644
index 00000000..5d9ef465
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/cmd/puppeth/module_node.go
@@ -0,0 +1,273 @@
+// Copyright 2017 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// go-ethereum is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with go-ethereum. If not, see .
+
+package main
+
+import (
+ "bytes"
+ "encoding/json"
+ "fmt"
+ "math/rand"
+ "path/filepath"
+ "strconv"
+ "strings"
+ "text/template"
+
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/log"
+)
+
+// nodeDockerfile is the Dockerfile required to run an Ethereum node.
+var nodeDockerfile = `
+FROM ethereum/client-go:latest
+
+ADD genesis.json /genesis.json
+{{if .Unlock}}
+ ADD signer.json /signer.json
+ ADD signer.pass /signer.pass
+{{end}}
+RUN \
+ echo 'geth --cache 512 init /genesis.json' > geth.sh && \{{if .Unlock}}
+ echo 'mkdir -p /root/.ethereum/keystore/ && cp /signer.json /root/.ethereum/keystore/' >> geth.sh && \{{end}}
+ echo $'exec geth --networkid {{.NetworkID}} --cache 512 --port {{.Port}} --nat extip:{{.IP}} --maxpeers {{.Peers}} {{.LightFlag}} --ethstats \'{{.Ethstats}}\' {{if .Bootnodes}}--bootnodes {{.Bootnodes}}{{end}} {{if .Etherbase}}--miner.etherbase {{.Etherbase}} --mine --miner.threads 1{{end}} {{if .Unlock}}--unlock 0 --password /signer.pass --mine{{end}} --miner.gastarget {{.GasTarget}} --miner.gaslimit {{.GasLimit}} --miner.gasprice {{.GasPrice}}' >> geth.sh
+
+ENTRYPOINT ["/bin/sh", "geth.sh"]
+`
+
+// nodeComposefile is the docker-compose.yml file required to deploy and maintain
+// an Ethereum node (bootnode or miner for now).
+var nodeComposefile = `
+version: '2'
+services:
+ {{.Type}}:
+ build: .
+ image: {{.Network}}/{{.Type}}
+ container_name: {{.Network}}_{{.Type}}_1
+ ports:
+ - "{{.Port}}:{{.Port}}"
+ - "{{.Port}}:{{.Port}}/udp"
+ volumes:
+ - {{.Datadir}}:/root/.ethereum{{if .Ethashdir}}
+ - {{.Ethashdir}}:/root/.ethash{{end}}
+ environment:
+ - PORT={{.Port}}/tcp
+ - TOTAL_PEERS={{.TotalPeers}}
+ - LIGHT_PEERS={{.LightPeers}}
+ - STATS_NAME={{.Ethstats}}
+ - MINER_NAME={{.Etherbase}}
+ - GAS_TARGET={{.GasTarget}}
+ - GAS_LIMIT={{.GasLimit}}
+ - GAS_PRICE={{.GasPrice}}
+ logging:
+ driver: "json-file"
+ options:
+ max-size: "1m"
+ max-file: "10"
+ restart: always
+`
+
+// deployNode deploys a new Ethereum node container to a remote machine via SSH,
+// docker and docker-compose. If an instance with the specified network name
+// already exists there, it will be overwritten!
+func deployNode(client *sshClient, network string, bootnodes []string, config *nodeInfos, nocache bool) ([]byte, error) {
+ kind := "sealnode"
+ if config.keyJSON == "" && config.etherbase == "" {
+ kind = "bootnode"
+ bootnodes = make([]string, 0)
+ }
+ // Generate the content to upload to the server
+ workdir := fmt.Sprintf("%d", rand.Int63())
+ files := make(map[string][]byte)
+
+ lightFlag := ""
+ if config.peersLight > 0 {
+ lightFlag = fmt.Sprintf("--lightpeers=%d --lightserv=50", config.peersLight)
+ }
+ dockerfile := new(bytes.Buffer)
+ template.Must(template.New("").Parse(nodeDockerfile)).Execute(dockerfile, map[string]interface{}{
+ "NetworkID": config.network,
+ "Port": config.port,
+ "IP": client.address,
+ "Peers": config.peersTotal,
+ "LightFlag": lightFlag,
+ "Bootnodes": strings.Join(bootnodes, ","),
+ "Ethstats": config.ethstats,
+ "Etherbase": config.etherbase,
+ "GasTarget": uint64(1000000 * config.gasTarget),
+ "GasLimit": uint64(1000000 * config.gasLimit),
+ "GasPrice": uint64(1000000000 * config.gasPrice),
+ "Unlock": config.keyJSON != "",
+ })
+ files[filepath.Join(workdir, "Dockerfile")] = dockerfile.Bytes()
+
+ composefile := new(bytes.Buffer)
+ template.Must(template.New("").Parse(nodeComposefile)).Execute(composefile, map[string]interface{}{
+ "Type": kind,
+ "Datadir": config.datadir,
+ "Ethashdir": config.ethashdir,
+ "Network": network,
+ "Port": config.port,
+ "TotalPeers": config.peersTotal,
+ "Light": config.peersLight > 0,
+ "LightPeers": config.peersLight,
+ "Ethstats": config.ethstats[:strings.Index(config.ethstats, ":")],
+ "Etherbase": config.etherbase,
+ "GasTarget": config.gasTarget,
+ "GasLimit": config.gasLimit,
+ "GasPrice": config.gasPrice,
+ })
+ files[filepath.Join(workdir, "docker-compose.yaml")] = composefile.Bytes()
+
+ files[filepath.Join(workdir, "genesis.json")] = config.genesis
+ if config.keyJSON != "" {
+ files[filepath.Join(workdir, "signer.json")] = []byte(config.keyJSON)
+ files[filepath.Join(workdir, "signer.pass")] = []byte(config.keyPass)
+ }
+ // Upload the deployment files to the remote server (and clean up afterwards)
+ if out, err := client.Upload(files); err != nil {
+ return out, err
+ }
+ defer client.Run("rm -rf " + workdir)
+
+ // Build and deploy the boot or seal node service
+ if nocache {
+ return nil, client.Stream(fmt.Sprintf("cd %s && docker-compose -p %s build --pull --no-cache && docker-compose -p %s up -d --force-recreate --timeout 60", workdir, network, network))
+ }
+ return nil, client.Stream(fmt.Sprintf("cd %s && docker-compose -p %s up -d --build --force-recreate --timeout 60", workdir, network))
+}
+
+// nodeInfos is returned from a boot or seal node status check to allow reporting
+// various configuration parameters.
+type nodeInfos struct {
+ genesis []byte
+ network int64
+ datadir string
+ ethashdir string
+ ethstats string
+ port int
+ enode string
+ peersTotal int
+ peersLight int
+ etherbase string
+ keyJSON string
+ keyPass string
+ gasTarget float64
+ gasLimit float64
+ gasPrice float64
+}
+
+// Report converts the typed struct into a plain string->string map, containing
+// most - but not all - fields for reporting to the user.
+func (info *nodeInfos) Report() map[string]string {
+ report := map[string]string{
+ "Data directory": info.datadir,
+ "Listener port": strconv.Itoa(info.port),
+ "Peer count (all total)": strconv.Itoa(info.peersTotal),
+ "Peer count (light nodes)": strconv.Itoa(info.peersLight),
+ "Ethstats username": info.ethstats,
+ }
+ if info.gasTarget > 0 {
+ // Miner or signer node
+ report["Gas price (minimum accepted)"] = fmt.Sprintf("%0.3f GWei", info.gasPrice)
+ report["Gas floor (baseline target)"] = fmt.Sprintf("%0.3f MGas", info.gasTarget)
+ report["Gas ceil (target maximum)"] = fmt.Sprintf("%0.3f MGas", info.gasLimit)
+
+ if info.etherbase != "" {
+ // Ethash proof-of-work miner
+ report["Ethash directory"] = info.ethashdir
+ report["Miner account"] = info.etherbase
+ }
+ if info.keyJSON != "" {
+ // Clique proof-of-authority signer
+ var key struct {
+ Address string `json:"address"`
+ }
+ if err := json.Unmarshal([]byte(info.keyJSON), &key); err == nil {
+ report["Signer account"] = common.HexToAddress(key.Address).Hex()
+ } else {
+ log.Error("Failed to retrieve signer address", "err", err)
+ }
+ }
+ }
+ return report
+}
+
+// checkNode does a health-check against a boot or seal node server to verify
+// whether it's running, and if yes, whether it's responsive.
+func checkNode(client *sshClient, network string, boot bool) (*nodeInfos, error) {
+ kind := "bootnode"
+ if !boot {
+ kind = "sealnode"
+ }
+ // Inspect a possible bootnode container on the host
+ infos, err := inspectContainer(client, fmt.Sprintf("%s_%s_1", network, kind))
+ if err != nil {
+ return nil, err
+ }
+ if !infos.running {
+ return nil, ErrServiceOffline
+ }
+ // Resolve a few types from the environmental variables
+ totalPeers, _ := strconv.Atoi(infos.envvars["TOTAL_PEERS"])
+ lightPeers, _ := strconv.Atoi(infos.envvars["LIGHT_PEERS"])
+ gasTarget, _ := strconv.ParseFloat(infos.envvars["GAS_TARGET"], 64)
+ gasLimit, _ := strconv.ParseFloat(infos.envvars["GAS_LIMIT"], 64)
+ gasPrice, _ := strconv.ParseFloat(infos.envvars["GAS_PRICE"], 64)
+
+ // Container available, retrieve its node ID and its genesis json
+ var out []byte
+ if out, err = client.Run(fmt.Sprintf("docker exec %s_%s_1 geth --exec admin.nodeInfo.enode --cache=16 attach", network, kind)); err != nil {
+ return nil, ErrServiceUnreachable
+ }
+ enode := bytes.Trim(bytes.TrimSpace(out), "\"")
+
+ if out, err = client.Run(fmt.Sprintf("docker exec %s_%s_1 cat /genesis.json", network, kind)); err != nil {
+ return nil, ErrServiceUnreachable
+ }
+ genesis := bytes.TrimSpace(out)
+
+ keyJSON, keyPass := "", ""
+ if out, err = client.Run(fmt.Sprintf("docker exec %s_%s_1 cat /signer.json", network, kind)); err == nil {
+ keyJSON = string(bytes.TrimSpace(out))
+ }
+ if out, err = client.Run(fmt.Sprintf("docker exec %s_%s_1 cat /signer.pass", network, kind)); err == nil {
+ keyPass = string(bytes.TrimSpace(out))
+ }
+ // Run a sanity check to see if the devp2p is reachable
+ port := infos.portmap[infos.envvars["PORT"]]
+ if err = checkPort(client.server, port); err != nil {
+ log.Warn(fmt.Sprintf("%s devp2p port seems unreachable", strings.Title(kind)), "server", client.server, "port", port, "err", err)
+ }
+ // Assemble and return the useful infos
+ stats := &nodeInfos{
+ genesis: genesis,
+ datadir: infos.volumes["/root/.ethereum"],
+ ethashdir: infos.volumes["/root/.ethash"],
+ port: port,
+ peersTotal: totalPeers,
+ peersLight: lightPeers,
+ ethstats: infos.envvars["STATS_NAME"],
+ etherbase: infos.envvars["MINER_NAME"],
+ keyJSON: keyJSON,
+ keyPass: keyPass,
+ gasTarget: gasTarget,
+ gasLimit: gasLimit,
+ gasPrice: gasPrice,
+ }
+ stats.enode = string(enode)
+
+ return stats, nil
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/puppeth/module_wallet.go b/vendor/github.com/ethereum/go-ethereum/cmd/puppeth/module_wallet.go
new file mode 100644
index 00000000..ebaa5b6a
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/cmd/puppeth/module_wallet.go
@@ -0,0 +1,201 @@
+// Copyright 2017 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// go-ethereum is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with go-ethereum. If not, see .
+
+package main
+
+import (
+ "bytes"
+ "fmt"
+ "html/template"
+ "math/rand"
+ "path/filepath"
+ "strconv"
+ "strings"
+
+ "github.com/ethereum/go-ethereum/log"
+)
+
+// walletDockerfile is the Dockerfile required to run a web wallet.
+var walletDockerfile = `
+FROM puppeth/wallet:latest
+
+ADD genesis.json /genesis.json
+
+RUN \
+ echo 'node server.js &' > wallet.sh && \
+ echo 'geth --cache 512 init /genesis.json' >> wallet.sh && \
+ echo $'exec geth --networkid {{.NetworkID}} --port {{.NodePort}} --bootnodes {{.Bootnodes}} --ethstats \'{{.Ethstats}}\' --cache=512 --rpc --rpcaddr=0.0.0.0 --rpccorsdomain "*" --rpcvhosts "*"' >> wallet.sh
+
+RUN \
+ sed -i 's/PuppethNetworkID/{{.NetworkID}}/g' dist/js/etherwallet-master.js && \
+ sed -i 's/PuppethNetwork/{{.Network}}/g' dist/js/etherwallet-master.js && \
+ sed -i 's/PuppethDenom/{{.Denom}}/g' dist/js/etherwallet-master.js && \
+ sed -i 's/PuppethHost/{{.Host}}/g' dist/js/etherwallet-master.js && \
+ sed -i 's/PuppethRPCPort/{{.RPCPort}}/g' dist/js/etherwallet-master.js
+
+ENTRYPOINT ["/bin/sh", "wallet.sh"]
+`
+
+// walletComposefile is the docker-compose.yml file required to deploy and
+// maintain a web wallet.
+var walletComposefile = `
+version: '2'
+services:
+ wallet:
+ build: .
+ image: {{.Network}}/wallet
+ container_name: {{.Network}}_wallet_1
+ ports:
+ - "{{.NodePort}}:{{.NodePort}}"
+ - "{{.NodePort}}:{{.NodePort}}/udp"
+ - "{{.RPCPort}}:8545"{{if not .VHost}}
+ - "{{.WebPort}}:80"{{end}}
+ volumes:
+ - {{.Datadir}}:/root/.ethereum
+ environment:
+ - NODE_PORT={{.NodePort}}/tcp
+ - STATS={{.Ethstats}}{{if .VHost}}
+ - VIRTUAL_HOST={{.VHost}}
+ - VIRTUAL_PORT=80{{end}}
+ logging:
+ driver: "json-file"
+ options:
+ max-size: "1m"
+ max-file: "10"
+ restart: always
+`
+
+// deployWallet deploys a new web wallet container to a remote machine via SSH,
+// docker and docker-compose. If an instance with the specified network name
+// already exists there, it will be overwritten!
+func deployWallet(client *sshClient, network string, bootnodes []string, config *walletInfos, nocache bool) ([]byte, error) {
+ // Generate the content to upload to the server
+ workdir := fmt.Sprintf("%d", rand.Int63())
+ files := make(map[string][]byte)
+
+ dockerfile := new(bytes.Buffer)
+ template.Must(template.New("").Parse(walletDockerfile)).Execute(dockerfile, map[string]interface{}{
+ "Network": strings.ToTitle(network),
+ "Denom": strings.ToUpper(network),
+ "NetworkID": config.network,
+ "NodePort": config.nodePort,
+ "RPCPort": config.rpcPort,
+ "Bootnodes": strings.Join(bootnodes, ","),
+ "Ethstats": config.ethstats,
+ "Host": client.address,
+ })
+ files[filepath.Join(workdir, "Dockerfile")] = dockerfile.Bytes()
+
+ composefile := new(bytes.Buffer)
+ template.Must(template.New("").Parse(walletComposefile)).Execute(composefile, map[string]interface{}{
+ "Datadir": config.datadir,
+ "Network": network,
+ "NodePort": config.nodePort,
+ "RPCPort": config.rpcPort,
+ "VHost": config.webHost,
+ "WebPort": config.webPort,
+ "Ethstats": config.ethstats[:strings.Index(config.ethstats, ":")],
+ })
+ files[filepath.Join(workdir, "docker-compose.yaml")] = composefile.Bytes()
+
+ files[filepath.Join(workdir, "genesis.json")] = config.genesis
+
+ // Upload the deployment files to the remote server (and clean up afterwards)
+ if out, err := client.Upload(files); err != nil {
+ return out, err
+ }
+ defer client.Run("rm -rf " + workdir)
+
+ // Build and deploy the boot or seal node service
+ if nocache {
+ return nil, client.Stream(fmt.Sprintf("cd %s && docker-compose -p %s build --pull --no-cache && docker-compose -p %s up -d --force-recreate --timeout 60", workdir, network, network))
+ }
+ return nil, client.Stream(fmt.Sprintf("cd %s && docker-compose -p %s up -d --build --force-recreate --timeout 60", workdir, network))
+}
+
+// walletInfos is returned from a web wallet status check to allow reporting
+// various configuration parameters.
+type walletInfos struct {
+ genesis []byte
+ network int64
+ datadir string
+ ethstats string
+ nodePort int
+ rpcPort int
+ webHost string
+ webPort int
+}
+
+// Report converts the typed struct into a plain string->string map, containing
+// most - but not all - fields for reporting to the user.
+func (info *walletInfos) Report() map[string]string {
+ report := map[string]string{
+ "Data directory": info.datadir,
+ "Ethstats username": info.ethstats,
+ "Node listener port ": strconv.Itoa(info.nodePort),
+ "RPC listener port ": strconv.Itoa(info.rpcPort),
+ "Website address ": info.webHost,
+ "Website listener port ": strconv.Itoa(info.webPort),
+ }
+ return report
+}
+
+// checkWallet does a health-check against web wallet server to verify whether
+// it's running, and if yes, whether it's responsive.
+func checkWallet(client *sshClient, network string) (*walletInfos, error) {
+ // Inspect a possible web wallet container on the host
+ infos, err := inspectContainer(client, fmt.Sprintf("%s_wallet_1", network))
+ if err != nil {
+ return nil, err
+ }
+ if !infos.running {
+ return nil, ErrServiceOffline
+ }
+ // Resolve the port from the host, or the reverse proxy
+ webPort := infos.portmap["80/tcp"]
+ if webPort == 0 {
+ if proxy, _ := checkNginx(client, network); proxy != nil {
+ webPort = proxy.port
+ }
+ }
+ if webPort == 0 {
+ return nil, ErrNotExposed
+ }
+ // Resolve the host from the reverse-proxy and the config values
+ host := infos.envvars["VIRTUAL_HOST"]
+ if host == "" {
+ host = client.server
+ }
+ // Run a sanity check to see if the devp2p and RPC ports are reachable
+ nodePort := infos.portmap[infos.envvars["NODE_PORT"]]
+ if err = checkPort(client.server, nodePort); err != nil {
+ log.Warn(fmt.Sprintf("Wallet devp2p port seems unreachable"), "server", client.server, "port", nodePort, "err", err)
+ }
+ rpcPort := infos.portmap["8545/tcp"]
+ if err = checkPort(client.server, rpcPort); err != nil {
+ log.Warn(fmt.Sprintf("Wallet RPC port seems unreachable"), "server", client.server, "port", rpcPort, "err", err)
+ }
+ // Assemble and return the useful infos
+ stats := &walletInfos{
+ datadir: infos.volumes["/root/.ethereum"],
+ nodePort: nodePort,
+ rpcPort: rpcPort,
+ webHost: host,
+ webPort: webPort,
+ ethstats: infos.envvars["STATS"],
+ }
+ return stats, nil
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/puppeth/puppeth.go b/vendor/github.com/ethereum/go-ethereum/cmd/puppeth/puppeth.go
new file mode 100644
index 00000000..c3de5f93
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/cmd/puppeth/puppeth.go
@@ -0,0 +1,65 @@
+// Copyright 2017 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// go-ethereum is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with go-ethereum. If not, see .
+
+// puppeth is a command to assemble and maintain private networks.
+package main
+
+import (
+ "math/rand"
+ "os"
+ "strings"
+ "time"
+
+ "github.com/ethereum/go-ethereum/log"
+ "gopkg.in/urfave/cli.v1"
+)
+
+// main is just a boring entry point to set up the CLI app.
+func main() {
+ app := cli.NewApp()
+ app.Name = "puppeth"
+ app.Usage = "assemble and maintain private Ethereum networks"
+ app.Flags = []cli.Flag{
+ cli.StringFlag{
+ Name: "network",
+ Usage: "name of the network to administer (no spaces or hyphens, please)",
+ },
+ cli.IntFlag{
+ Name: "loglevel",
+ Value: 3,
+ Usage: "log level to emit to the screen",
+ },
+ }
+ app.Before = func(c *cli.Context) error {
+ // Set up the logger to print everything and the random generator
+ log.Root().SetHandler(log.LvlFilterHandler(log.Lvl(c.Int("loglevel")), log.StreamHandler(os.Stdout, log.TerminalFormat(true))))
+ rand.Seed(time.Now().UnixNano())
+
+ return nil
+ }
+ app.Action = runWizard
+ app.Run(os.Args)
+}
+
+// runWizard start the wizard and relinquish control to it.
+func runWizard(c *cli.Context) error {
+ network := c.String("network")
+ if strings.Contains(network, " ") || strings.Contains(network, "-") || strings.ToLower(network) != network {
+ log.Crit("No spaces, hyphens or capital letters allowed in network name")
+ }
+ makeWizard(c.String("network")).run()
+ return nil
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/puppeth/ssh.go b/vendor/github.com/ethereum/go-ethereum/cmd/puppeth/ssh.go
new file mode 100644
index 00000000..c5075960
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/cmd/puppeth/ssh.go
@@ -0,0 +1,253 @@
+// Copyright 2017 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// go-ethereum is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with go-ethereum. If not, see .
+
+package main
+
+import (
+ "bufio"
+ "bytes"
+ "errors"
+ "fmt"
+ "io/ioutil"
+ "net"
+ "os"
+ "os/user"
+ "path/filepath"
+ "strings"
+
+ "github.com/ethereum/go-ethereum/log"
+ "golang.org/x/crypto/ssh"
+ "golang.org/x/crypto/ssh/terminal"
+)
+
+// sshClient is a small wrapper around Go's SSH client with a few utility methods
+// implemented on top.
+type sshClient struct {
+ server string // Server name or IP without port number
+ address string // IP address of the remote server
+ pubkey []byte // RSA public key to authenticate the server
+ client *ssh.Client
+ logger log.Logger
+}
+
+// dial establishes an SSH connection to a remote node using the current user and
+// the user's configured private RSA key. If that fails, password authentication
+// is fallen back to. server can be a string like user:identity@server:port.
+func dial(server string, pubkey []byte) (*sshClient, error) {
+ // Figure out username, identity, hostname and port
+ hostname := ""
+ hostport := server
+ username := ""
+ identity := "id_rsa" // default
+
+ if strings.Contains(server, "@") {
+ prefix := server[:strings.Index(server, "@")]
+ if strings.Contains(prefix, ":") {
+ username = prefix[:strings.Index(prefix, ":")]
+ identity = prefix[strings.Index(prefix, ":")+1:]
+ } else {
+ username = prefix
+ }
+ hostport = server[strings.Index(server, "@")+1:]
+ }
+ if strings.Contains(hostport, ":") {
+ hostname = hostport[:strings.Index(hostport, ":")]
+ } else {
+ hostname = hostport
+ hostport += ":22"
+ }
+ logger := log.New("server", server)
+ logger.Debug("Attempting to establish SSH connection")
+
+ user, err := user.Current()
+ if err != nil {
+ return nil, err
+ }
+ if username == "" {
+ username = user.Username
+ }
+ // Configure the supported authentication methods (private key and password)
+ var auths []ssh.AuthMethod
+
+ path := filepath.Join(user.HomeDir, ".ssh", identity)
+ if buf, err := ioutil.ReadFile(path); err != nil {
+ log.Warn("No SSH key, falling back to passwords", "path", path, "err", err)
+ } else {
+ key, err := ssh.ParsePrivateKey(buf)
+ if err != nil {
+ fmt.Printf("What's the decryption password for %s? (won't be echoed)\n>", path)
+ blob, err := terminal.ReadPassword(int(os.Stdin.Fd()))
+ fmt.Println()
+ if err != nil {
+ log.Warn("Couldn't read password", "err", err)
+ }
+ key, err := ssh.ParsePrivateKeyWithPassphrase(buf, blob)
+ if err != nil {
+ log.Warn("Failed to decrypt SSH key, falling back to passwords", "path", path, "err", err)
+ } else {
+ auths = append(auths, ssh.PublicKeys(key))
+ }
+ } else {
+ auths = append(auths, ssh.PublicKeys(key))
+ }
+ }
+ auths = append(auths, ssh.PasswordCallback(func() (string, error) {
+ fmt.Printf("What's the login password for %s at %s? (won't be echoed)\n> ", username, server)
+ blob, err := terminal.ReadPassword(int(os.Stdin.Fd()))
+
+ fmt.Println()
+ return string(blob), err
+ }))
+ // Resolve the IP address of the remote server
+ addr, err := net.LookupHost(hostname)
+ if err != nil {
+ return nil, err
+ }
+ if len(addr) == 0 {
+ return nil, errors.New("no IPs associated with domain")
+ }
+ // Try to dial in to the remote server
+ logger.Trace("Dialing remote SSH server", "user", username)
+ keycheck := func(hostname string, remote net.Addr, key ssh.PublicKey) error {
+ // If no public key is known for SSH, ask the user to confirm
+ if pubkey == nil {
+ fmt.Println()
+ fmt.Printf("The authenticity of host '%s (%s)' can't be established.\n", hostname, remote)
+ fmt.Printf("SSH key fingerprint is %s [MD5]\n", ssh.FingerprintLegacyMD5(key))
+ fmt.Printf("Are you sure you want to continue connecting (yes/no)? ")
+
+ text, err := bufio.NewReader(os.Stdin).ReadString('\n')
+ switch {
+ case err != nil:
+ return err
+ case strings.TrimSpace(text) == "yes":
+ pubkey = key.Marshal()
+ return nil
+ default:
+ return fmt.Errorf("unknown auth choice: %v", text)
+ }
+ }
+ // If a public key exists for this SSH server, check that it matches
+ if bytes.Equal(pubkey, key.Marshal()) {
+ return nil
+ }
+ // We have a mismatch, forbid connecting
+ return errors.New("ssh key mismatch, readd the machine to update")
+ }
+ client, err := ssh.Dial("tcp", hostport, &ssh.ClientConfig{User: username, Auth: auths, HostKeyCallback: keycheck})
+ if err != nil {
+ return nil, err
+ }
+ // Connection established, return our utility wrapper
+ c := &sshClient{
+ server: hostname,
+ address: addr[0],
+ pubkey: pubkey,
+ client: client,
+ logger: logger,
+ }
+ if err := c.init(); err != nil {
+ client.Close()
+ return nil, err
+ }
+ return c, nil
+}
+
+// init runs some initialization commands on the remote server to ensure it's
+// capable of acting as puppeth target.
+func (client *sshClient) init() error {
+ client.logger.Debug("Verifying if docker is available")
+ if out, err := client.Run("docker version"); err != nil {
+ if len(out) == 0 {
+ return err
+ }
+ return fmt.Errorf("docker configured incorrectly: %s", out)
+ }
+ client.logger.Debug("Verifying if docker-compose is available")
+ if out, err := client.Run("docker-compose version"); err != nil {
+ if len(out) == 0 {
+ return err
+ }
+ return fmt.Errorf("docker-compose configured incorrectly: %s", out)
+ }
+ return nil
+}
+
+// Close terminates the connection to an SSH server.
+func (client *sshClient) Close() error {
+ return client.client.Close()
+}
+
+// Run executes a command on the remote server and returns the combined output
+// along with any error status.
+func (client *sshClient) Run(cmd string) ([]byte, error) {
+ // Establish a single command session
+ session, err := client.client.NewSession()
+ if err != nil {
+ return nil, err
+ }
+ defer session.Close()
+
+ // Execute the command and return any output
+ client.logger.Trace("Running command on remote server", "cmd", cmd)
+ return session.CombinedOutput(cmd)
+}
+
+// Stream executes a command on the remote server and streams all outputs into
+// the local stdout and stderr streams.
+func (client *sshClient) Stream(cmd string) error {
+ // Establish a single command session
+ session, err := client.client.NewSession()
+ if err != nil {
+ return err
+ }
+ defer session.Close()
+
+ session.Stdout = os.Stdout
+ session.Stderr = os.Stderr
+
+ // Execute the command and return any output
+ client.logger.Trace("Streaming command on remote server", "cmd", cmd)
+ return session.Run(cmd)
+}
+
+// Upload copies the set of files to a remote server via SCP, creating any non-
+// existing folders in the mean time.
+func (client *sshClient) Upload(files map[string][]byte) ([]byte, error) {
+ // Establish a single command session
+ session, err := client.client.NewSession()
+ if err != nil {
+ return nil, err
+ }
+ defer session.Close()
+
+ // Create a goroutine that streams the SCP content
+ go func() {
+ out, _ := session.StdinPipe()
+ defer out.Close()
+
+ for file, content := range files {
+ client.logger.Trace("Uploading file to server", "file", file, "bytes", len(content))
+
+ fmt.Fprintln(out, "D0755", 0, filepath.Dir(file)) // Ensure the folder exists
+ fmt.Fprintln(out, "C0644", len(content), filepath.Base(file)) // Create the actual file
+ out.Write(content) // Stream the data content
+ fmt.Fprint(out, "\x00") // Transfer end with \x00
+ fmt.Fprintln(out, "E") // Leave directory (simpler)
+ }
+ }()
+ return session.CombinedOutput("/usr/bin/scp -v -tr ./")
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/puppeth/testdata/stureby_aleth.json b/vendor/github.com/ethereum/go-ethereum/cmd/puppeth/testdata/stureby_aleth.json
new file mode 100644
index 00000000..1ef1d8ae
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/cmd/puppeth/testdata/stureby_aleth.json
@@ -0,0 +1,112 @@
+{
+ "sealEngine":"Ethash",
+ "params":{
+ "accountStartNonce":"0x00",
+ "maximumExtraDataSize":"0x20",
+ "homesteadForkBlock":"0x2710",
+ "daoHardforkBlock":"0x00",
+ "EIP150ForkBlock":"0x3a98",
+ "EIP158ForkBlock":"0x59d8",
+ "byzantiumForkBlock":"0x7530",
+ "constantinopleForkBlock":"0x9c40",
+ "minGasLimit":"0x1388",
+ "maxGasLimit":"0x7fffffffffffffff",
+ "tieBreakingGas":false,
+ "gasLimitBoundDivisor":"0x0400",
+ "minimumDifficulty":"0x20000",
+ "difficultyBoundDivisor":"0x0800",
+ "durationLimit":"0x0d",
+ "blockReward":"0x4563918244F40000",
+ "networkID":"0x4cb2e",
+ "chainID":"0x4cb2e",
+ "allowFutureBlocks":false
+ },
+ "genesis":{
+ "nonce":"0x0000000000000000",
+ "difficulty":"0x20000",
+ "mixHash":"0x0000000000000000000000000000000000000000000000000000000000000000",
+ "author":"0x0000000000000000000000000000000000000000",
+ "timestamp":"0x59a4e76d",
+ "parentHash":"0x0000000000000000000000000000000000000000000000000000000000000000",
+ "extraData":"0x0000000000000000000000000000000000000000000000000000000b4dc0ffee",
+ "gasLimit":"0x47b760"
+ },
+ "accounts":{
+ "0000000000000000000000000000000000000001":{
+ "balance":"1",
+ "precompiled":{
+ "name":"ecrecover",
+ "linear":{
+ "base":3000,
+ "word":0
+ }
+ }
+ },
+ "0000000000000000000000000000000000000002":{
+ "balance":"1",
+ "precompiled":{
+ "name":"sha256",
+ "linear":{
+ "base":60,
+ "word":12
+ }
+ }
+ },
+ "0000000000000000000000000000000000000003":{
+ "balance":"1",
+ "precompiled":{
+ "name":"ripemd160",
+ "linear":{
+ "base":600,
+ "word":120
+ }
+ }
+ },
+ "0000000000000000000000000000000000000004":{
+ "balance":"1",
+ "precompiled":{
+ "name":"identity",
+ "linear":{
+ "base":15,
+ "word":3
+ }
+ }
+ },
+ "0000000000000000000000000000000000000005":{
+ "balance":"1",
+ "precompiled":{
+ "name":"modexp",
+ "startingBlock":"0x7530"
+ }
+ },
+ "0000000000000000000000000000000000000006":{
+ "balance":"1",
+ "precompiled":{
+ "name":"alt_bn128_G1_add",
+ "startingBlock":"0x7530",
+ "linear":{
+ "base":500,
+ "word":0
+ }
+ }
+ },
+ "0000000000000000000000000000000000000007":{
+ "balance":"1",
+ "precompiled":{
+ "name":"alt_bn128_G1_mul",
+ "startingBlock":"0x7530",
+ "linear":{
+ "base":40000,
+ "word":0
+ }
+ }
+ },
+ "0000000000000000000000000000000000000008":{
+ "balance":"1",
+ "precompiled":{
+ "name":"alt_bn128_pairing_product",
+ "startingBlock":"0x7530"
+ }
+ }
+ }
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/puppeth/testdata/stureby_geth.json b/vendor/github.com/ethereum/go-ethereum/cmd/puppeth/testdata/stureby_geth.json
new file mode 100644
index 00000000..c8c3b3c9
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/cmd/puppeth/testdata/stureby_geth.json
@@ -0,0 +1,47 @@
+{
+ "config": {
+ "ethash":{},
+ "chainId": 314158,
+ "homesteadBlock": 10000,
+ "eip150Block": 15000,
+ "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "eip155Block": 23000,
+ "eip158Block": 23000,
+ "byzantiumBlock": 30000,
+ "constantinopleBlock": 40000
+ },
+ "nonce": "0x0",
+ "timestamp": "0x59a4e76d",
+ "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "extraData": "0x0000000000000000000000000000000000000000000000000000000b4dc0ffee",
+ "gasLimit": "0x47b760",
+ "difficulty": "0x20000",
+ "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "coinbase": "0x0000000000000000000000000000000000000000",
+ "alloc": {
+ "0000000000000000000000000000000000000001": {
+ "balance": "0x01"
+ },
+ "0000000000000000000000000000000000000002": {
+ "balance": "0x01"
+ },
+ "0000000000000000000000000000000000000003": {
+ "balance": "0x01"
+ },
+ "0000000000000000000000000000000000000004": {
+ "balance": "0x01"
+ },
+ "0000000000000000000000000000000000000005": {
+ "balance": "0x01"
+ },
+ "0000000000000000000000000000000000000006": {
+ "balance": "0x01"
+ },
+ "0000000000000000000000000000000000000007": {
+ "balance": "0x01"
+ },
+ "0000000000000000000000000000000000000008": {
+ "balance": "0x01"
+ }
+ }
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/puppeth/testdata/stureby_parity.json b/vendor/github.com/ethereum/go-ethereum/cmd/puppeth/testdata/stureby_parity.json
new file mode 100644
index 00000000..f3fa8386
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/cmd/puppeth/testdata/stureby_parity.json
@@ -0,0 +1,181 @@
+{
+ "name":"Stureby",
+ "dataDir":"stureby",
+ "engine":{
+ "Ethash":{
+ "params":{
+ "minimumDifficulty":"0x20000",
+ "difficultyBoundDivisor":"0x800",
+ "durationLimit":"0xd",
+ "blockReward":{
+ "0x0":"0x4563918244f40000",
+ "0x7530":"0x29a2241af62c0000",
+ "0x9c40":"0x1bc16d674ec80000"
+ },
+ "homesteadTransition":"0x2710",
+ "eip100bTransition":"0x7530",
+ "difficultyBombDelays":{
+ "0x7530":"0x2dc6c0",
+ "0x9c40":"0x1e8480"
+ }
+ }
+ }
+ },
+ "params":{
+ "accountStartNonce":"0x0",
+ "maximumExtraDataSize":"0x20",
+ "gasLimitBoundDivisor":"0x400",
+ "minGasLimit":"0x1388",
+ "networkID":"0x4cb2e",
+ "chainID":"0x4cb2e",
+ "maxCodeSize":"0x6000",
+ "maxCodeSizeTransition":"0x0",
+ "eip98Transition": "0x7fffffffffffffff",
+ "eip150Transition":"0x3a98",
+ "eip160Transition":"0x59d8",
+ "eip161abcTransition":"0x59d8",
+ "eip161dTransition":"0x59d8",
+ "eip155Transition":"0x59d8",
+ "eip140Transition":"0x7530",
+ "eip211Transition":"0x7530",
+ "eip214Transition":"0x7530",
+ "eip658Transition":"0x7530",
+ "eip145Transition":"0x9c40",
+ "eip1014Transition":"0x9c40",
+ "eip1052Transition":"0x9c40",
+ "eip1283Transition":"0x9c40"
+ },
+ "genesis":{
+ "seal":{
+ "ethereum":{
+ "nonce":"0x0000000000000000",
+ "mixHash":"0x0000000000000000000000000000000000000000000000000000000000000000"
+ }
+ },
+ "difficulty":"0x20000",
+ "author":"0x0000000000000000000000000000000000000000",
+ "timestamp":"0x59a4e76d",
+ "parentHash":"0x0000000000000000000000000000000000000000000000000000000000000000",
+ "extraData":"0x0000000000000000000000000000000000000000000000000000000b4dc0ffee",
+ "gasLimit":"0x47b760"
+ },
+ "nodes":[
+ "enode://dfa7aca3f5b635fbfe7d0b20575f25e40d9e27b4bfbb3cf74364a42023ad9f25c1a4383bcc8cced86ee511a7d03415345a4df05be37f1dff040e4c780699f1c0@168.61.153.255:31303",
+ "enode://ef441b20dd70aeabf0eac35c3b8a2854e5ce04db0e30be9152ea9fd129359dcbb3f803993303ff5781c755dfd7223f3fe43505f583cccb740949407677412ba9@40.74.91.252:31303",
+ "enode://953b5ea1c8987cf46008232a0160324fd00d41320ecf00e23af86ec8f5396b19eb57ddab37c78141be56f62e9077de4f4dfa0747fa768ed8c8531bbfb1046237@40.70.214.166:31303",
+ "enode://276e613dd4b277a66591e565711e6c8bb107f0905248a9f8f8228c1a87992e156e5114bb9937c02824a9d9d25f76340442cf86e2028bf5293cae19904fb2b98e@35.178.251.52:30303",
+ "enode://064c820d41e52ed7d426ac64b60506c2998235bedc7e67cb497c6faf7bb4fc54fe56fc82d0add3180b747c0c4f40a1108a6f84d7d0629ed606d504528e61cc57@3.8.5.3:30303",
+ "enode://90069fdabcc5e684fa5d59430bebbb12755d9362dfe5006a1485b13d71a78a3812d36e74dd7d88e50b51add01e097ea80f16263aeaa4f0230db6c79e2a97e7ca@217.29.191.142:30303",
+ "enode://0aac74b7fd28726275e466acb5e03bc88a95927e9951eb66b5efb239b2f798ada0690853b2f2823fe4efa408f0f3d4dd258430bc952a5ff70677b8625b3e3b14@40.115.33.57:40404",
+ "enode://0b96415a10f835106d83e090a0528eed5e7887e5c802a6d084e9f1993a9d0fc713781e6e4101f6365e9b91259712f291acc0a9e6e667e22023050d602c36fbe2@40.115.33.57:40414"
+ ],
+ "accounts":{
+ "0000000000000000000000000000000000000001":{
+ "balance":"1",
+ "nonce":"0",
+ "builtin":{
+ "name":"ecrecover",
+ "pricing":{
+ "linear":{
+ "base":3000,
+ "word":0
+ }
+ }
+ }
+ },
+ "0000000000000000000000000000000000000002":{
+ "balance":"1",
+ "nonce":"0",
+ "builtin":{
+ "name":"sha256",
+ "pricing":{
+ "linear":{
+ "base":60,
+ "word":12
+ }
+ }
+ }
+ },
+ "0000000000000000000000000000000000000003":{
+ "balance":"1",
+ "nonce":"0",
+ "builtin":{
+ "name":"ripemd160",
+ "pricing":{
+ "linear":{
+ "base":600,
+ "word":120
+ }
+ }
+ }
+ },
+ "0000000000000000000000000000000000000004":{
+ "balance":"1",
+ "nonce":"0",
+ "builtin":{
+ "name":"identity",
+ "pricing":{
+ "linear":{
+ "base":15,
+ "word":3
+ }
+ }
+ }
+ },
+ "0000000000000000000000000000000000000005":{
+ "balance":"1",
+ "nonce":"0",
+ "builtin":{
+ "name":"modexp",
+ "activate_at":"0x7530",
+ "pricing":{
+ "modexp":{
+ "divisor":20
+ }
+ }
+ }
+ },
+ "0000000000000000000000000000000000000006":{
+ "balance":"1",
+ "nonce":"0",
+ "builtin":{
+ "name":"alt_bn128_add",
+ "activate_at":"0x7530",
+ "pricing":{
+ "linear":{
+ "base":500,
+ "word":0
+ }
+ }
+ }
+ },
+ "0000000000000000000000000000000000000007":{
+ "balance":"1",
+ "nonce":"0",
+ "builtin":{
+ "name":"alt_bn128_mul",
+ "activate_at":"0x7530",
+ "pricing":{
+ "linear":{
+ "base":40000,
+ "word":0
+ }
+ }
+ }
+ },
+ "0000000000000000000000000000000000000008":{
+ "balance":"1",
+ "nonce":"0",
+ "builtin":{
+ "name":"alt_bn128_pairing",
+ "activate_at":"0x7530",
+ "pricing":{
+ "alt_bn128_pairing":{
+ "base":100000,
+ "pair":80000
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/puppeth/wizard.go b/vendor/github.com/ethereum/go-ethereum/cmd/puppeth/wizard.go
new file mode 100644
index 00000000..83536506
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/cmd/puppeth/wizard.go
@@ -0,0 +1,368 @@
+// Copyright 2017 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// go-ethereum is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with go-ethereum. If not, see .
+
+package main
+
+import (
+ "bufio"
+ "encoding/json"
+ "fmt"
+ "io/ioutil"
+ "math/big"
+ "net"
+ "net/url"
+ "os"
+ "path/filepath"
+ "sort"
+ "strconv"
+ "strings"
+ "sync"
+
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/core"
+ "github.com/ethereum/go-ethereum/log"
+ "golang.org/x/crypto/ssh/terminal"
+)
+
+// config contains all the configurations needed by puppeth that should be saved
+// between sessions.
+type config struct {
+ path string // File containing the configuration values
+ bootnodes []string // Bootnodes to always connect to by all nodes
+ ethstats string // Ethstats settings to cache for node deploys
+
+ Genesis *core.Genesis `json:"genesis,omitempty"` // Genesis block to cache for node deploys
+ Servers map[string][]byte `json:"servers,omitempty"`
+}
+
+// servers retrieves an alphabetically sorted list of servers.
+func (c config) servers() []string {
+ servers := make([]string, 0, len(c.Servers))
+ for server := range c.Servers {
+ servers = append(servers, server)
+ }
+ sort.Strings(servers)
+
+ return servers
+}
+
+// flush dumps the contents of config to disk.
+func (c config) flush() {
+ os.MkdirAll(filepath.Dir(c.path), 0755)
+
+ out, _ := json.MarshalIndent(c, "", " ")
+ if err := ioutil.WriteFile(c.path, out, 0644); err != nil {
+ log.Warn("Failed to save puppeth configs", "file", c.path, "err", err)
+ }
+}
+
+type wizard struct {
+ network string // Network name to manage
+ conf config // Configurations from previous runs
+
+ servers map[string]*sshClient // SSH connections to servers to administer
+ services map[string][]string // Ethereum services known to be running on servers
+
+ in *bufio.Reader // Wrapper around stdin to allow reading user input
+ lock sync.Mutex // Lock to protect configs during concurrent service discovery
+}
+
+// read reads a single line from stdin, trimming if from spaces.
+func (w *wizard) read() string {
+ fmt.Printf("> ")
+ text, err := w.in.ReadString('\n')
+ if err != nil {
+ log.Crit("Failed to read user input", "err", err)
+ }
+ return strings.TrimSpace(text)
+}
+
+// readString reads a single line from stdin, trimming if from spaces, enforcing
+// non-emptyness.
+func (w *wizard) readString() string {
+ for {
+ fmt.Printf("> ")
+ text, err := w.in.ReadString('\n')
+ if err != nil {
+ log.Crit("Failed to read user input", "err", err)
+ }
+ if text = strings.TrimSpace(text); text != "" {
+ return text
+ }
+ }
+}
+
+// readDefaultString reads a single line from stdin, trimming if from spaces. If
+// an empty line is entered, the default value is returned.
+func (w *wizard) readDefaultString(def string) string {
+ fmt.Printf("> ")
+ text, err := w.in.ReadString('\n')
+ if err != nil {
+ log.Crit("Failed to read user input", "err", err)
+ }
+ if text = strings.TrimSpace(text); text != "" {
+ return text
+ }
+ return def
+}
+
+// readDefaultYesNo reads a single line from stdin, trimming if from spaces and
+// interpreting it as a 'yes' or a 'no'. If an empty line is entered, the default
+// value is returned.
+func (w *wizard) readDefaultYesNo(def bool) bool {
+ for {
+ fmt.Printf("> ")
+ text, err := w.in.ReadString('\n')
+ if err != nil {
+ log.Crit("Failed to read user input", "err", err)
+ }
+ if text = strings.ToLower(strings.TrimSpace(text)); text == "" {
+ return def
+ }
+ if text == "y" || text == "yes" {
+ return true
+ }
+ if text == "n" || text == "no" {
+ return false
+ }
+ log.Error("Invalid input, expected 'y', 'yes', 'n', 'no' or empty")
+ }
+}
+
+// readURL reads a single line from stdin, trimming if from spaces and trying to
+// interpret it as a URL (http, https or file).
+func (w *wizard) readURL() *url.URL {
+ for {
+ fmt.Printf("> ")
+ text, err := w.in.ReadString('\n')
+ if err != nil {
+ log.Crit("Failed to read user input", "err", err)
+ }
+ uri, err := url.Parse(strings.TrimSpace(text))
+ if err != nil {
+ log.Error("Invalid input, expected URL", "err", err)
+ continue
+ }
+ return uri
+ }
+}
+
+// readInt reads a single line from stdin, trimming if from spaces, enforcing it
+// to parse into an integer.
+func (w *wizard) readInt() int {
+ for {
+ fmt.Printf("> ")
+ text, err := w.in.ReadString('\n')
+ if err != nil {
+ log.Crit("Failed to read user input", "err", err)
+ }
+ if text = strings.TrimSpace(text); text == "" {
+ continue
+ }
+ val, err := strconv.Atoi(strings.TrimSpace(text))
+ if err != nil {
+ log.Error("Invalid input, expected integer", "err", err)
+ continue
+ }
+ return val
+ }
+}
+
+// readDefaultInt reads a single line from stdin, trimming if from spaces, enforcing
+// it to parse into an integer. If an empty line is entered, the default value is
+// returned.
+func (w *wizard) readDefaultInt(def int) int {
+ for {
+ fmt.Printf("> ")
+ text, err := w.in.ReadString('\n')
+ if err != nil {
+ log.Crit("Failed to read user input", "err", err)
+ }
+ if text = strings.TrimSpace(text); text == "" {
+ return def
+ }
+ val, err := strconv.Atoi(strings.TrimSpace(text))
+ if err != nil {
+ log.Error("Invalid input, expected integer", "err", err)
+ continue
+ }
+ return val
+ }
+}
+
+// readDefaultBigInt reads a single line from stdin, trimming if from spaces,
+// enforcing it to parse into a big integer. If an empty line is entered, the
+// default value is returned.
+func (w *wizard) readDefaultBigInt(def *big.Int) *big.Int {
+ for {
+ fmt.Printf("> ")
+ text, err := w.in.ReadString('\n')
+ if err != nil {
+ log.Crit("Failed to read user input", "err", err)
+ }
+ if text = strings.TrimSpace(text); text == "" {
+ return def
+ }
+ val, ok := new(big.Int).SetString(text, 0)
+ if !ok {
+ log.Error("Invalid input, expected big integer")
+ continue
+ }
+ return val
+ }
+}
+
+/*
+// readFloat reads a single line from stdin, trimming if from spaces, enforcing it
+// to parse into a float.
+func (w *wizard) readFloat() float64 {
+ for {
+ fmt.Printf("> ")
+ text, err := w.in.ReadString('\n')
+ if err != nil {
+ log.Crit("Failed to read user input", "err", err)
+ }
+ if text = strings.TrimSpace(text); text == "" {
+ continue
+ }
+ val, err := strconv.ParseFloat(strings.TrimSpace(text), 64)
+ if err != nil {
+ log.Error("Invalid input, expected float", "err", err)
+ continue
+ }
+ return val
+ }
+}
+*/
+
+// readDefaultFloat reads a single line from stdin, trimming if from spaces, enforcing
+// it to parse into a float. If an empty line is entered, the default value is returned.
+func (w *wizard) readDefaultFloat(def float64) float64 {
+ for {
+ fmt.Printf("> ")
+ text, err := w.in.ReadString('\n')
+ if err != nil {
+ log.Crit("Failed to read user input", "err", err)
+ }
+ if text = strings.TrimSpace(text); text == "" {
+ return def
+ }
+ val, err := strconv.ParseFloat(strings.TrimSpace(text), 64)
+ if err != nil {
+ log.Error("Invalid input, expected float", "err", err)
+ continue
+ }
+ return val
+ }
+}
+
+// readPassword reads a single line from stdin, trimming it from the trailing new
+// line and returns it. The input will not be echoed.
+func (w *wizard) readPassword() string {
+ fmt.Printf("> ")
+ text, err := terminal.ReadPassword(int(os.Stdin.Fd()))
+ if err != nil {
+ log.Crit("Failed to read password", "err", err)
+ }
+ fmt.Println()
+ return string(text)
+}
+
+// readAddress reads a single line from stdin, trimming if from spaces and converts
+// it to an Ethereum address.
+func (w *wizard) readAddress() *common.Address {
+ for {
+ // Read the address from the user
+ fmt.Printf("> 0x")
+ text, err := w.in.ReadString('\n')
+ if err != nil {
+ log.Crit("Failed to read user input", "err", err)
+ }
+ if text = strings.TrimSpace(text); text == "" {
+ return nil
+ }
+ // Make sure it looks ok and return it if so
+ if len(text) != 40 {
+ log.Error("Invalid address length, please retry")
+ continue
+ }
+ bigaddr, _ := new(big.Int).SetString(text, 16)
+ address := common.BigToAddress(bigaddr)
+ return &address
+ }
+}
+
+// readDefaultAddress reads a single line from stdin, trimming if from spaces and
+// converts it to an Ethereum address. If an empty line is entered, the default
+// value is returned.
+func (w *wizard) readDefaultAddress(def common.Address) common.Address {
+ for {
+ // Read the address from the user
+ fmt.Printf("> 0x")
+ text, err := w.in.ReadString('\n')
+ if err != nil {
+ log.Crit("Failed to read user input", "err", err)
+ }
+ if text = strings.TrimSpace(text); text == "" {
+ return def
+ }
+ // Make sure it looks ok and return it if so
+ if len(text) != 40 {
+ log.Error("Invalid address length, please retry")
+ continue
+ }
+ bigaddr, _ := new(big.Int).SetString(text, 16)
+ return common.BigToAddress(bigaddr)
+ }
+}
+
+// readJSON reads a raw JSON message and returns it.
+func (w *wizard) readJSON() string {
+ var blob json.RawMessage
+
+ for {
+ fmt.Printf("> ")
+ if err := json.NewDecoder(w.in).Decode(&blob); err != nil {
+ log.Error("Invalid JSON, please try again", "err", err)
+ continue
+ }
+ return string(blob)
+ }
+}
+
+// readIPAddress reads a single line from stdin, trimming if from spaces and
+// returning it if it's convertible to an IP address. The reason for keeping
+// the user input format instead of returning a Go net.IP is to match with
+// weird formats used by ethstats, which compares IPs textually, not by value.
+func (w *wizard) readIPAddress() string {
+ for {
+ // Read the IP address from the user
+ fmt.Printf("> ")
+ text, err := w.in.ReadString('\n')
+ if err != nil {
+ log.Crit("Failed to read user input", "err", err)
+ }
+ if text = strings.TrimSpace(text); text == "" {
+ return ""
+ }
+ // Make sure it looks ok and return it if so
+ if ip := net.ParseIP(text); ip == nil {
+ log.Error("Invalid IP address, please retry")
+ continue
+ }
+ return text
+ }
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/puppeth/wizard_dashboard.go b/vendor/github.com/ethereum/go-ethereum/cmd/puppeth/wizard_dashboard.go
new file mode 100644
index 00000000..8a837084
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/cmd/puppeth/wizard_dashboard.go
@@ -0,0 +1,158 @@
+// Copyright 2017 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// go-ethereum is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with go-ethereum. If not, see .
+
+package main
+
+import (
+ "fmt"
+
+ "github.com/ethereum/go-ethereum/log"
+)
+
+// deployDashboard queries the user for various input on deploying a web-service
+// dashboard, after which is pushes the container.
+func (w *wizard) deployDashboard() {
+ // Select the server to interact with
+ server := w.selectServer()
+ if server == "" {
+ return
+ }
+ client := w.servers[server]
+
+ // Retrieve any active dashboard configurations from the server
+ infos, err := checkDashboard(client, w.network)
+ if err != nil {
+ infos = &dashboardInfos{
+ port: 80,
+ host: client.server,
+ }
+ }
+ existed := err == nil
+
+ // Figure out which port to listen on
+ fmt.Println()
+ fmt.Printf("Which port should the dashboard listen on? (default = %d)\n", infos.port)
+ infos.port = w.readDefaultInt(infos.port)
+
+ // Figure which virtual-host to deploy the dashboard on
+ infos.host, err = w.ensureVirtualHost(client, infos.port, infos.host)
+ if err != nil {
+ log.Error("Failed to decide on dashboard host", "err", err)
+ return
+ }
+ // Port and proxy settings retrieved, figure out which services are available
+ available := make(map[string][]string)
+ for server, services := range w.services {
+ for _, service := range services {
+ available[service] = append(available[service], server)
+ }
+ }
+ for _, service := range []string{"ethstats", "explorer", "wallet", "faucet"} {
+ // Gather all the locally hosted pages of this type
+ var pages []string
+ for _, server := range available[service] {
+ client := w.servers[server]
+ if client == nil {
+ continue
+ }
+ // If there's a service running on the machine, retrieve it's port number
+ var port int
+ switch service {
+ case "ethstats":
+ if infos, err := checkEthstats(client, w.network); err == nil {
+ port = infos.port
+ }
+ case "explorer":
+ if infos, err := checkExplorer(client, w.network); err == nil {
+ port = infos.webPort
+ }
+ case "wallet":
+ if infos, err := checkWallet(client, w.network); err == nil {
+ port = infos.webPort
+ }
+ case "faucet":
+ if infos, err := checkFaucet(client, w.network); err == nil {
+ port = infos.port
+ }
+ }
+ if page, err := resolve(client, w.network, service, port); err == nil && page != "" {
+ pages = append(pages, page)
+ }
+ }
+ // Prompt the user to chose one, enter manually or simply not list this service
+ defLabel, defChoice := "don't list", len(pages)+2
+ if len(pages) > 0 {
+ defLabel, defChoice = pages[0], 1
+ }
+ fmt.Println()
+ fmt.Printf("Which %s service to list? (default = %s)\n", service, defLabel)
+ for i, page := range pages {
+ fmt.Printf(" %d. %s\n", i+1, page)
+ }
+ fmt.Printf(" %d. List external %s service\n", len(pages)+1, service)
+ fmt.Printf(" %d. Don't list any %s service\n", len(pages)+2, service)
+
+ choice := w.readDefaultInt(defChoice)
+ if choice < 0 || choice > len(pages)+2 {
+ log.Error("Invalid listing choice, aborting")
+ return
+ }
+ var page string
+ switch {
+ case choice <= len(pages):
+ page = pages[choice-1]
+ case choice == len(pages)+1:
+ fmt.Println()
+ fmt.Printf("Which address is the external %s service at?\n", service)
+ page = w.readString()
+ default:
+ // No service hosting for this
+ }
+ // Save the users choice
+ switch service {
+ case "ethstats":
+ infos.ethstats = page
+ case "explorer":
+ infos.explorer = page
+ case "wallet":
+ infos.wallet = page
+ case "faucet":
+ infos.faucet = page
+ }
+ }
+ // If we have ethstats running, ask whether to make the secret public or not
+ if w.conf.ethstats != "" {
+ fmt.Println()
+ fmt.Println("Include ethstats secret on dashboard (y/n)? (default = yes)")
+ infos.trusted = w.readDefaultYesNo(true)
+ }
+ // Try to deploy the dashboard container on the host
+ nocache := false
+ if existed {
+ fmt.Println()
+ fmt.Printf("Should the dashboard be built from scratch (y/n)? (default = no)\n")
+ nocache = w.readDefaultYesNo(false)
+ }
+ if out, err := deployDashboard(client, w.network, &w.conf, infos, nocache); err != nil {
+ log.Error("Failed to deploy dashboard container", "err", err)
+ if len(out) > 0 {
+ fmt.Printf("%s\n", out)
+ }
+ return
+ }
+ // All ok, run a network scan to pick any changes up
+ w.networkStats()
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/puppeth/wizard_ethstats.go b/vendor/github.com/ethereum/go-ethereum/cmd/puppeth/wizard_ethstats.go
new file mode 100644
index 00000000..58ff3efb
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/cmd/puppeth/wizard_ethstats.go
@@ -0,0 +1,126 @@
+// Copyright 2017 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// go-ethereum is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with go-ethereum. If not, see .
+
+package main
+
+import (
+ "fmt"
+ "sort"
+
+ "github.com/ethereum/go-ethereum/log"
+)
+
+// deployEthstats queries the user for various input on deploying an ethstats
+// monitoring server, after which it executes it.
+func (w *wizard) deployEthstats() {
+ // Select the server to interact with
+ server := w.selectServer()
+ if server == "" {
+ return
+ }
+ client := w.servers[server]
+
+ // Retrieve any active ethstats configurations from the server
+ infos, err := checkEthstats(client, w.network)
+ if err != nil {
+ infos = ðstatsInfos{
+ port: 80,
+ host: client.server,
+ secret: "",
+ }
+ }
+ existed := err == nil
+
+ // Figure out which port to listen on
+ fmt.Println()
+ fmt.Printf("Which port should ethstats listen on? (default = %d)\n", infos.port)
+ infos.port = w.readDefaultInt(infos.port)
+
+ // Figure which virtual-host to deploy ethstats on
+ if infos.host, err = w.ensureVirtualHost(client, infos.port, infos.host); err != nil {
+ log.Error("Failed to decide on ethstats host", "err", err)
+ return
+ }
+ // Port and proxy settings retrieved, figure out the secret and boot ethstats
+ fmt.Println()
+ if infos.secret == "" {
+ fmt.Printf("What should be the secret password for the API? (must not be empty)\n")
+ infos.secret = w.readString()
+ } else {
+ fmt.Printf("What should be the secret password for the API? (default = %s)\n", infos.secret)
+ infos.secret = w.readDefaultString(infos.secret)
+ }
+ // Gather any blacklists to ban from reporting
+ if existed {
+ fmt.Println()
+ fmt.Printf("Keep existing IP %v blacklist (y/n)? (default = yes)\n", infos.banned)
+ if !w.readDefaultYesNo(true) {
+ // The user might want to clear the entire list, although generally probably not
+ fmt.Println()
+ fmt.Printf("Clear out blacklist and start over (y/n)? (default = no)\n")
+ if w.readDefaultYesNo(false) {
+ infos.banned = nil
+ }
+ // Offer the user to explicitly add/remove certain IP addresses
+ fmt.Println()
+ fmt.Println("Which additional IP addresses should be blacklisted?")
+ for {
+ if ip := w.readIPAddress(); ip != "" {
+ infos.banned = append(infos.banned, ip)
+ continue
+ }
+ break
+ }
+ fmt.Println()
+ fmt.Println("Which IP addresses should not be blacklisted?")
+ for {
+ if ip := w.readIPAddress(); ip != "" {
+ for i, addr := range infos.banned {
+ if ip == addr {
+ infos.banned = append(infos.banned[:i], infos.banned[i+1:]...)
+ break
+ }
+ }
+ continue
+ }
+ break
+ }
+ sort.Strings(infos.banned)
+ }
+ }
+ // Try to deploy the ethstats server on the host
+ nocache := false
+ if existed {
+ fmt.Println()
+ fmt.Printf("Should the ethstats be built from scratch (y/n)? (default = no)\n")
+ nocache = w.readDefaultYesNo(false)
+ }
+ trusted := make([]string, 0, len(w.servers))
+ for _, client := range w.servers {
+ if client != nil {
+ trusted = append(trusted, client.address)
+ }
+ }
+ if out, err := deployEthstats(client, w.network, infos.port, infos.secret, infos.host, trusted, infos.banned, nocache); err != nil {
+ log.Error("Failed to deploy ethstats container", "err", err)
+ if len(out) > 0 {
+ fmt.Printf("%s\n", out)
+ }
+ return
+ }
+ // All ok, run a network scan to pick any changes up
+ w.networkStats()
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/puppeth/wizard_explorer.go b/vendor/github.com/ethereum/go-ethereum/cmd/puppeth/wizard_explorer.go
new file mode 100644
index 00000000..a128fb9f
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/cmd/puppeth/wizard_explorer.go
@@ -0,0 +1,117 @@
+// Copyright 2017 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// go-ethereum is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with go-ethereum. If not, see .
+
+package main
+
+import (
+ "encoding/json"
+ "fmt"
+ "time"
+
+ "github.com/ethereum/go-ethereum/log"
+)
+
+// deployExplorer creates a new block explorer based on some user input.
+func (w *wizard) deployExplorer() {
+ // Do some sanity check before the user wastes time on input
+ if w.conf.Genesis == nil {
+ log.Error("No genesis block configured")
+ return
+ }
+ if w.conf.ethstats == "" {
+ log.Error("No ethstats server configured")
+ return
+ }
+ if w.conf.Genesis.Config.Ethash == nil {
+ log.Error("Only ethash network supported")
+ return
+ }
+ // Select the server to interact with
+ server := w.selectServer()
+ if server == "" {
+ return
+ }
+ client := w.servers[server]
+
+ // Retrieve any active node configurations from the server
+ infos, err := checkExplorer(client, w.network)
+ if err != nil {
+ infos = &explorerInfos{
+ nodePort: 30303, webPort: 80, webHost: client.server,
+ }
+ }
+ existed := err == nil
+
+ chainspec, err := newParityChainSpec(w.network, w.conf.Genesis, w.conf.bootnodes)
+ if err != nil {
+ log.Error("Failed to create chain spec for explorer", "err", err)
+ return
+ }
+ chain, _ := json.MarshalIndent(chainspec, "", " ")
+
+ // Figure out which port to listen on
+ fmt.Println()
+ fmt.Printf("Which port should the explorer listen on? (default = %d)\n", infos.webPort)
+ infos.webPort = w.readDefaultInt(infos.webPort)
+
+ // Figure which virtual-host to deploy ethstats on
+ if infos.webHost, err = w.ensureVirtualHost(client, infos.webPort, infos.webHost); err != nil {
+ log.Error("Failed to decide on explorer host", "err", err)
+ return
+ }
+ // Figure out where the user wants to store the persistent data
+ fmt.Println()
+ if infos.datadir == "" {
+ fmt.Printf("Where should data be stored on the remote machine?\n")
+ infos.datadir = w.readString()
+ } else {
+ fmt.Printf("Where should data be stored on the remote machine? (default = %s)\n", infos.datadir)
+ infos.datadir = w.readDefaultString(infos.datadir)
+ }
+ // Figure out which port to listen on
+ fmt.Println()
+ fmt.Printf("Which TCP/UDP port should the archive node listen on? (default = %d)\n", infos.nodePort)
+ infos.nodePort = w.readDefaultInt(infos.nodePort)
+
+ // Set a proper name to report on the stats page
+ fmt.Println()
+ if infos.ethstats == "" {
+ fmt.Printf("What should the explorer be called on the stats page?\n")
+ infos.ethstats = w.readString() + ":" + w.conf.ethstats
+ } else {
+ fmt.Printf("What should the explorer be called on the stats page? (default = %s)\n", infos.ethstats)
+ infos.ethstats = w.readDefaultString(infos.ethstats) + ":" + w.conf.ethstats
+ }
+ // Try to deploy the explorer on the host
+ nocache := false
+ if existed {
+ fmt.Println()
+ fmt.Printf("Should the explorer be built from scratch (y/n)? (default = no)\n")
+ nocache = w.readDefaultYesNo(false)
+ }
+ if out, err := deployExplorer(client, w.network, chain, infos, nocache); err != nil {
+ log.Error("Failed to deploy explorer container", "err", err)
+ if len(out) > 0 {
+ fmt.Printf("%s\n", out)
+ }
+ return
+ }
+ // All ok, run a network scan to pick any changes up
+ log.Info("Waiting for node to finish booting")
+ time.Sleep(3 * time.Second)
+
+ w.networkStats()
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/puppeth/wizard_faucet.go b/vendor/github.com/ethereum/go-ethereum/cmd/puppeth/wizard_faucet.go
new file mode 100644
index 00000000..9068c1d3
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/cmd/puppeth/wizard_faucet.go
@@ -0,0 +1,180 @@
+// Copyright 2017 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// go-ethereum is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with go-ethereum. If not, see .
+
+package main
+
+import (
+ "encoding/json"
+ "fmt"
+
+ "github.com/ethereum/go-ethereum/accounts/keystore"
+ "github.com/ethereum/go-ethereum/log"
+)
+
+// deployFaucet queries the user for various input on deploying a faucet, after
+// which it executes it.
+func (w *wizard) deployFaucet() {
+ // Select the server to interact with
+ server := w.selectServer()
+ if server == "" {
+ return
+ }
+ client := w.servers[server]
+
+ // Retrieve any active faucet configurations from the server
+ infos, err := checkFaucet(client, w.network)
+ if err != nil {
+ infos = &faucetInfos{
+ node: &nodeInfos{port: 30303, peersTotal: 25},
+ port: 80,
+ host: client.server,
+ amount: 1,
+ minutes: 1440,
+ tiers: 3,
+ }
+ }
+ existed := err == nil
+
+ infos.node.genesis, _ = json.MarshalIndent(w.conf.Genesis, "", " ")
+ infos.node.network = w.conf.Genesis.Config.ChainID.Int64()
+
+ // Figure out which port to listen on
+ fmt.Println()
+ fmt.Printf("Which port should the faucet listen on? (default = %d)\n", infos.port)
+ infos.port = w.readDefaultInt(infos.port)
+
+ // Figure which virtual-host to deploy ethstats on
+ if infos.host, err = w.ensureVirtualHost(client, infos.port, infos.host); err != nil {
+ log.Error("Failed to decide on faucet host", "err", err)
+ return
+ }
+ // Port and proxy settings retrieved, figure out the funding amount per period configurations
+ fmt.Println()
+ fmt.Printf("How many Ethers to release per request? (default = %d)\n", infos.amount)
+ infos.amount = w.readDefaultInt(infos.amount)
+
+ fmt.Println()
+ fmt.Printf("How many minutes to enforce between requests? (default = %d)\n", infos.minutes)
+ infos.minutes = w.readDefaultInt(infos.minutes)
+
+ fmt.Println()
+ fmt.Printf("How many funding tiers to feature (x2.5 amounts, x3 timeout)? (default = %d)\n", infos.tiers)
+ infos.tiers = w.readDefaultInt(infos.tiers)
+ if infos.tiers == 0 {
+ log.Error("At least one funding tier must be set")
+ return
+ }
+ // Accessing the reCaptcha service requires API authorizations, request it
+ if infos.captchaToken != "" {
+ fmt.Println()
+ fmt.Println("Reuse previous reCaptcha API authorization (y/n)? (default = yes)")
+ if !w.readDefaultYesNo(true) {
+ infos.captchaToken, infos.captchaSecret = "", ""
+ }
+ }
+ if infos.captchaToken == "" {
+ // No previous authorization (or old one discarded)
+ fmt.Println()
+ fmt.Println("Enable reCaptcha protection against robots (y/n)? (default = no)")
+ if !w.readDefaultYesNo(false) {
+ log.Warn("Users will be able to requests funds via automated scripts")
+ } else {
+ // Captcha protection explicitly requested, read the site and secret keys
+ fmt.Println()
+ fmt.Printf("What is the reCaptcha site key to authenticate human users?\n")
+ infos.captchaToken = w.readString()
+
+ fmt.Println()
+ fmt.Printf("What is the reCaptcha secret key to verify authentications? (won't be echoed)\n")
+ infos.captchaSecret = w.readPassword()
+ }
+ }
+ // Figure out where the user wants to store the persistent data
+ fmt.Println()
+ if infos.node.datadir == "" {
+ fmt.Printf("Where should data be stored on the remote machine?\n")
+ infos.node.datadir = w.readString()
+ } else {
+ fmt.Printf("Where should data be stored on the remote machine? (default = %s)\n", infos.node.datadir)
+ infos.node.datadir = w.readDefaultString(infos.node.datadir)
+ }
+ // Figure out which port to listen on
+ fmt.Println()
+ fmt.Printf("Which TCP/UDP port should the light client listen on? (default = %d)\n", infos.node.port)
+ infos.node.port = w.readDefaultInt(infos.node.port)
+
+ // Set a proper name to report on the stats page
+ fmt.Println()
+ if infos.node.ethstats == "" {
+ fmt.Printf("What should the node be called on the stats page?\n")
+ infos.node.ethstats = w.readString() + ":" + w.conf.ethstats
+ } else {
+ fmt.Printf("What should the node be called on the stats page? (default = %s)\n", infos.node.ethstats)
+ infos.node.ethstats = w.readDefaultString(infos.node.ethstats) + ":" + w.conf.ethstats
+ }
+ // Load up the credential needed to release funds
+ if infos.node.keyJSON != "" {
+ if key, err := keystore.DecryptKey([]byte(infos.node.keyJSON), infos.node.keyPass); err != nil {
+ infos.node.keyJSON, infos.node.keyPass = "", ""
+ } else {
+ fmt.Println()
+ fmt.Printf("Reuse previous (%s) funding account (y/n)? (default = yes)\n", key.Address.Hex())
+ if !w.readDefaultYesNo(true) {
+ infos.node.keyJSON, infos.node.keyPass = "", ""
+ }
+ }
+ }
+ for i := 0; i < 3 && infos.node.keyJSON == ""; i++ {
+ fmt.Println()
+ fmt.Println("Please paste the faucet's funding account key JSON:")
+ infos.node.keyJSON = w.readJSON()
+
+ fmt.Println()
+ fmt.Println("What's the unlock password for the account? (won't be echoed)")
+ infos.node.keyPass = w.readPassword()
+
+ if _, err := keystore.DecryptKey([]byte(infos.node.keyJSON), infos.node.keyPass); err != nil {
+ log.Error("Failed to decrypt key with given passphrase")
+ infos.node.keyJSON = ""
+ infos.node.keyPass = ""
+ }
+ }
+ // Check if the user wants to run the faucet in debug mode (noauth)
+ noauth := "n"
+ if infos.noauth {
+ noauth = "y"
+ }
+ fmt.Println()
+ fmt.Printf("Permit non-authenticated funding requests (y/n)? (default = %v)\n", infos.noauth)
+ infos.noauth = w.readDefaultString(noauth) != "n"
+
+ // Try to deploy the faucet server on the host
+ nocache := false
+ if existed {
+ fmt.Println()
+ fmt.Printf("Should the faucet be built from scratch (y/n)? (default = no)\n")
+ nocache = w.readDefaultYesNo(false)
+ }
+ if out, err := deployFaucet(client, w.network, w.conf.bootnodes, infos, nocache); err != nil {
+ log.Error("Failed to deploy faucet container", "err", err)
+ if len(out) > 0 {
+ fmt.Printf("%s\n", out)
+ }
+ return
+ }
+ // All ok, run a network scan to pick any changes up
+ w.networkStats()
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/puppeth/wizard_genesis.go b/vendor/github.com/ethereum/go-ethereum/cmd/puppeth/wizard_genesis.go
new file mode 100644
index 00000000..6aed09f1
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/cmd/puppeth/wizard_genesis.go
@@ -0,0 +1,299 @@
+// Copyright 2017 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// go-ethereum is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with go-ethereum. If not, see .
+
+package main
+
+import (
+ "bytes"
+ "encoding/json"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "math/big"
+ "math/rand"
+ "net/http"
+ "os"
+ "path/filepath"
+ "time"
+
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/core"
+ "github.com/ethereum/go-ethereum/log"
+ "github.com/ethereum/go-ethereum/params"
+)
+
+// makeGenesis creates a new genesis struct based on some user input.
+func (w *wizard) makeGenesis() {
+ // Construct a default genesis block
+ genesis := &core.Genesis{
+ Timestamp: uint64(time.Now().Unix()),
+ GasLimit: 4700000,
+ Difficulty: big.NewInt(524288),
+ Alloc: make(core.GenesisAlloc),
+ Config: ¶ms.ChainConfig{
+ HomesteadBlock: big.NewInt(1),
+ EIP150Block: big.NewInt(2),
+ EIP155Block: big.NewInt(3),
+ EIP158Block: big.NewInt(3),
+ ByzantiumBlock: big.NewInt(4),
+ ConstantinopleBlock: big.NewInt(5),
+ },
+ }
+ // Figure out which consensus engine to choose
+ fmt.Println()
+ fmt.Println("Which consensus engine to use? (default = clique)")
+ fmt.Println(" 1. Ethash - proof-of-work")
+ fmt.Println(" 2. Clique - proof-of-authority")
+
+ choice := w.read()
+ switch {
+ case choice == "1":
+ // In case of ethash, we're pretty much done
+ genesis.Config.Ethash = new(params.EthashConfig)
+ genesis.ExtraData = make([]byte, 32)
+
+ case choice == "" || choice == "2":
+ // In the case of clique, configure the consensus parameters
+ genesis.Difficulty = big.NewInt(1)
+ genesis.Config.Clique = ¶ms.CliqueConfig{
+ Period: 15,
+ Epoch: 30000,
+ }
+ fmt.Println()
+ fmt.Println("How many seconds should blocks take? (default = 15)")
+ genesis.Config.Clique.Period = uint64(w.readDefaultInt(15))
+
+ // We also need the initial list of signers
+ fmt.Println()
+ fmt.Println("Which accounts are allowed to seal? (mandatory at least one)")
+
+ var signers []common.Address
+ for {
+ if address := w.readAddress(); address != nil {
+ signers = append(signers, *address)
+ continue
+ }
+ if len(signers) > 0 {
+ break
+ }
+ }
+ // Sort the signers and embed into the extra-data section
+ for i := 0; i < len(signers); i++ {
+ for j := i + 1; j < len(signers); j++ {
+ if bytes.Compare(signers[i][:], signers[j][:]) > 0 {
+ signers[i], signers[j] = signers[j], signers[i]
+ }
+ }
+ }
+ genesis.ExtraData = make([]byte, 32+len(signers)*common.AddressLength+65)
+ for i, signer := range signers {
+ copy(genesis.ExtraData[32+i*common.AddressLength:], signer[:])
+ }
+
+ default:
+ log.Crit("Invalid consensus engine choice", "choice", choice)
+ }
+ // Consensus all set, just ask for initial funds and go
+ fmt.Println()
+ fmt.Println("Which accounts should be pre-funded? (advisable at least one)")
+ for {
+ // Read the address of the account to fund
+ if address := w.readAddress(); address != nil {
+ genesis.Alloc[*address] = core.GenesisAccount{
+ Balance: new(big.Int).Lsh(big.NewInt(1), 256-7), // 2^256 / 128 (allow many pre-funds without balance overflows)
+ }
+ continue
+ }
+ break
+ }
+ fmt.Println()
+ fmt.Println("Should the precompile-addresses (0x1 .. 0xff) be pre-funded with 1 wei? (advisable yes)")
+ if w.readDefaultYesNo(true) {
+ // Add a batch of precompile balances to avoid them getting deleted
+ for i := int64(0); i < 256; i++ {
+ genesis.Alloc[common.BigToAddress(big.NewInt(i))] = core.GenesisAccount{Balance: big.NewInt(1)}
+ }
+ }
+ // Query the user for some custom extras
+ fmt.Println()
+ fmt.Println("Specify your chain/network ID if you want an explicit one (default = random)")
+ genesis.Config.ChainID = new(big.Int).SetUint64(uint64(w.readDefaultInt(rand.Intn(65536))))
+
+ // All done, store the genesis and flush to disk
+ log.Info("Configured new genesis block")
+
+ w.conf.Genesis = genesis
+ w.conf.flush()
+}
+
+// importGenesis imports a Geth genesis spec into puppeth.
+func (w *wizard) importGenesis() {
+ // Request the genesis JSON spec URL from the user
+ fmt.Println()
+ fmt.Println("Where's the genesis file? (local file or http/https url)")
+ url := w.readURL()
+
+ // Convert the various allowed URLs to a reader stream
+ var reader io.Reader
+
+ switch url.Scheme {
+ case "http", "https":
+ // Remote web URL, retrieve it via an HTTP client
+ res, err := http.Get(url.String())
+ if err != nil {
+ log.Error("Failed to retrieve remote genesis", "err", err)
+ return
+ }
+ defer res.Body.Close()
+ reader = res.Body
+
+ case "":
+ // Schemaless URL, interpret as a local file
+ file, err := os.Open(url.String())
+ if err != nil {
+ log.Error("Failed to open local genesis", "err", err)
+ return
+ }
+ defer file.Close()
+ reader = file
+
+ default:
+ log.Error("Unsupported genesis URL scheme", "scheme", url.Scheme)
+ return
+ }
+ // Parse the genesis file and inject it successful
+ var genesis core.Genesis
+ if err := json.NewDecoder(reader).Decode(&genesis); err != nil {
+ log.Error("Invalid genesis spec: %v", err)
+ return
+ }
+ log.Info("Imported genesis block")
+
+ w.conf.Genesis = &genesis
+ w.conf.flush()
+}
+
+// manageGenesis permits the modification of chain configuration parameters in
+// a genesis config and the export of the entire genesis spec.
+func (w *wizard) manageGenesis() {
+ // Figure out whether to modify or export the genesis
+ fmt.Println()
+ fmt.Println(" 1. Modify existing fork rules")
+ fmt.Println(" 2. Export genesis configurations")
+ fmt.Println(" 3. Remove genesis configuration")
+
+ choice := w.read()
+ switch choice {
+ case "1":
+ // Fork rule updating requested, iterate over each fork
+ fmt.Println()
+ fmt.Printf("Which block should Homestead come into effect? (default = %v)\n", w.conf.Genesis.Config.HomesteadBlock)
+ w.conf.Genesis.Config.HomesteadBlock = w.readDefaultBigInt(w.conf.Genesis.Config.HomesteadBlock)
+
+ fmt.Println()
+ fmt.Printf("Which block should EIP150 (Tangerine Whistle) come into effect? (default = %v)\n", w.conf.Genesis.Config.EIP150Block)
+ w.conf.Genesis.Config.EIP150Block = w.readDefaultBigInt(w.conf.Genesis.Config.EIP150Block)
+
+ fmt.Println()
+ fmt.Printf("Which block should EIP155 (Spurious Dragon) come into effect? (default = %v)\n", w.conf.Genesis.Config.EIP155Block)
+ w.conf.Genesis.Config.EIP155Block = w.readDefaultBigInt(w.conf.Genesis.Config.EIP155Block)
+
+ fmt.Println()
+ fmt.Printf("Which block should EIP158/161 (also Spurious Dragon) come into effect? (default = %v)\n", w.conf.Genesis.Config.EIP158Block)
+ w.conf.Genesis.Config.EIP158Block = w.readDefaultBigInt(w.conf.Genesis.Config.EIP158Block)
+
+ fmt.Println()
+ fmt.Printf("Which block should Byzantium come into effect? (default = %v)\n", w.conf.Genesis.Config.ByzantiumBlock)
+ w.conf.Genesis.Config.ByzantiumBlock = w.readDefaultBigInt(w.conf.Genesis.Config.ByzantiumBlock)
+
+ fmt.Println()
+ fmt.Printf("Which block should Constantinople come into effect? (default = %v)\n", w.conf.Genesis.Config.ConstantinopleBlock)
+ w.conf.Genesis.Config.ConstantinopleBlock = w.readDefaultBigInt(w.conf.Genesis.Config.ConstantinopleBlock)
+ if w.conf.Genesis.Config.PetersburgBlock == nil {
+ w.conf.Genesis.Config.PetersburgBlock = w.conf.Genesis.Config.ConstantinopleBlock
+ }
+ fmt.Println()
+ fmt.Printf("Which block should Constantinople-Fix (remove EIP-1283) come into effect? (default = %v)\n", w.conf.Genesis.Config.PetersburgBlock)
+ w.conf.Genesis.Config.PetersburgBlock = w.readDefaultBigInt(w.conf.Genesis.Config.PetersburgBlock)
+
+ out, _ := json.MarshalIndent(w.conf.Genesis.Config, "", " ")
+ fmt.Printf("Chain configuration updated:\n\n%s\n", out)
+
+ w.conf.flush()
+
+ case "2":
+ // Save whatever genesis configuration we currently have
+ fmt.Println()
+ fmt.Printf("Which folder to save the genesis specs into? (default = current)\n")
+ fmt.Printf(" Will create %s.json, %s-aleth.json, %s-harmony.json, %s-parity.json\n", w.network, w.network, w.network, w.network)
+
+ folder := w.readDefaultString(".")
+ if err := os.MkdirAll(folder, 0755); err != nil {
+ log.Error("Failed to create spec folder", "folder", folder, "err", err)
+ return
+ }
+ out, _ := json.MarshalIndent(w.conf.Genesis, "", " ")
+
+ // Export the native genesis spec used by puppeth and Geth
+ gethJson := filepath.Join(folder, fmt.Sprintf("%s.json", w.network))
+ if err := ioutil.WriteFile((gethJson), out, 0644); err != nil {
+ log.Error("Failed to save genesis file", "err", err)
+ return
+ }
+ log.Info("Saved native genesis chain spec", "path", gethJson)
+
+ // Export the genesis spec used by Aleth (formerly C++ Ethereum)
+ if spec, err := newAlethGenesisSpec(w.network, w.conf.Genesis); err != nil {
+ log.Error("Failed to create Aleth chain spec", "err", err)
+ } else {
+ saveGenesis(folder, w.network, "aleth", spec)
+ }
+ // Export the genesis spec used by Parity
+ if spec, err := newParityChainSpec(w.network, w.conf.Genesis, []string{}); err != nil {
+ log.Error("Failed to create Parity chain spec", "err", err)
+ } else {
+ saveGenesis(folder, w.network, "parity", spec)
+ }
+ // Export the genesis spec used by Harmony (formerly EthereumJ
+ saveGenesis(folder, w.network, "harmony", w.conf.Genesis)
+
+ case "3":
+ // Make sure we don't have any services running
+ if len(w.conf.servers()) > 0 {
+ log.Error("Genesis reset requires all services and servers torn down")
+ return
+ }
+ log.Info("Genesis block destroyed")
+
+ w.conf.Genesis = nil
+ w.conf.flush()
+ default:
+ log.Error("That's not something I can do")
+ return
+ }
+}
+
+// saveGenesis JSON encodes an arbitrary genesis spec into a pre-defined file.
+func saveGenesis(folder, network, client string, spec interface{}) {
+ path := filepath.Join(folder, fmt.Sprintf("%s-%s.json", network, client))
+
+ out, _ := json.Marshal(spec)
+ if err := ioutil.WriteFile(path, out, 0644); err != nil {
+ log.Error("Failed to save genesis file", "client", client, "err", err)
+ return
+ }
+ log.Info("Saved genesis chain spec", "client", client, "path", path)
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/puppeth/wizard_intro.go b/vendor/github.com/ethereum/go-ethereum/cmd/puppeth/wizard_intro.go
new file mode 100644
index 00000000..75fb04b7
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/cmd/puppeth/wizard_intro.go
@@ -0,0 +1,169 @@
+// Copyright 2017 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// go-ethereum is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with go-ethereum. If not, see .
+
+package main
+
+import (
+ "bufio"
+ "encoding/json"
+ "fmt"
+ "io/ioutil"
+ "os"
+ "path/filepath"
+ "strings"
+ "sync"
+
+ "github.com/ethereum/go-ethereum/log"
+)
+
+// makeWizard creates and returns a new puppeth wizard.
+func makeWizard(network string) *wizard {
+ return &wizard{
+ network: network,
+ conf: config{
+ Servers: make(map[string][]byte),
+ },
+ servers: make(map[string]*sshClient),
+ services: make(map[string][]string),
+ in: bufio.NewReader(os.Stdin),
+ }
+}
+
+// run displays some useful infos to the user, starting on the journey of
+// setting up a new or managing an existing Ethereum private network.
+func (w *wizard) run() {
+ fmt.Println("+-----------------------------------------------------------+")
+ fmt.Println("| Welcome to puppeth, your Ethereum private network manager |")
+ fmt.Println("| |")
+ fmt.Println("| This tool lets you create a new Ethereum network down to |")
+ fmt.Println("| the genesis block, bootnodes, miners and ethstats servers |")
+ fmt.Println("| without the hassle that it would normally entail. |")
+ fmt.Println("| |")
+ fmt.Println("| Puppeth uses SSH to dial in to remote servers, and builds |")
+ fmt.Println("| its network components out of Docker containers using the |")
+ fmt.Println("| docker-compose toolset. |")
+ fmt.Println("+-----------------------------------------------------------+")
+ fmt.Println()
+
+ // Make sure we have a good network name to work with fmt.Println()
+ // Docker accepts hyphens in image names, but doesn't like it for container names
+ if w.network == "" {
+ fmt.Println("Please specify a network name to administer (no spaces, hyphens or capital letters please)")
+ for {
+ w.network = w.readString()
+ if !strings.Contains(w.network, " ") && !strings.Contains(w.network, "-") && strings.ToLower(w.network) == w.network {
+ fmt.Printf("\nSweet, you can set this via --network=%s next time!\n\n", w.network)
+ break
+ }
+ log.Error("I also like to live dangerously, still no spaces, hyphens or capital letters")
+ }
+ }
+ log.Info("Administering Ethereum network", "name", w.network)
+
+ // Load initial configurations and connect to all live servers
+ w.conf.path = filepath.Join(os.Getenv("HOME"), ".puppeth", w.network)
+
+ blob, err := ioutil.ReadFile(w.conf.path)
+ if err != nil {
+ log.Warn("No previous configurations found", "path", w.conf.path)
+ } else if err := json.Unmarshal(blob, &w.conf); err != nil {
+ log.Crit("Previous configuration corrupted", "path", w.conf.path, "err", err)
+ } else {
+ // Dial all previously known servers concurrently
+ var pend sync.WaitGroup
+ for server, pubkey := range w.conf.Servers {
+ pend.Add(1)
+
+ go func(server string, pubkey []byte) {
+ defer pend.Done()
+
+ log.Info("Dialing previously configured server", "server", server)
+ client, err := dial(server, pubkey)
+ if err != nil {
+ log.Error("Previous server unreachable", "server", server, "err", err)
+ }
+ w.lock.Lock()
+ w.servers[server] = client
+ w.lock.Unlock()
+ }(server, pubkey)
+ }
+ pend.Wait()
+ w.networkStats()
+ }
+ // Basics done, loop ad infinitum about what to do
+ for {
+ fmt.Println()
+ fmt.Println("What would you like to do? (default = stats)")
+ fmt.Println(" 1. Show network stats")
+ if w.conf.Genesis == nil {
+ fmt.Println(" 2. Configure new genesis")
+ } else {
+ fmt.Println(" 2. Manage existing genesis")
+ }
+ if len(w.servers) == 0 {
+ fmt.Println(" 3. Track new remote server")
+ } else {
+ fmt.Println(" 3. Manage tracked machines")
+ }
+ if len(w.services) == 0 {
+ fmt.Println(" 4. Deploy network components")
+ } else {
+ fmt.Println(" 4. Manage network components")
+ }
+
+ choice := w.read()
+ switch {
+ case choice == "" || choice == "1":
+ w.networkStats()
+
+ case choice == "2":
+ if w.conf.Genesis == nil {
+ fmt.Println()
+ fmt.Println("What would you like to do? (default = create)")
+ fmt.Println(" 1. Create new genesis from scratch")
+ fmt.Println(" 2. Import already existing genesis")
+
+ choice := w.read()
+ switch {
+ case choice == "" || choice == "1":
+ w.makeGenesis()
+ case choice == "2":
+ w.importGenesis()
+ default:
+ log.Error("That's not something I can do")
+ }
+ } else {
+ w.manageGenesis()
+ }
+ case choice == "3":
+ if len(w.servers) == 0 {
+ if w.makeServer() != "" {
+ w.networkStats()
+ }
+ } else {
+ w.manageServers()
+ }
+ case choice == "4":
+ if len(w.services) == 0 {
+ w.deployComponent()
+ } else {
+ w.manageComponents()
+ }
+ default:
+ log.Error("That's not something I can do")
+ }
+ }
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/puppeth/wizard_netstats.go b/vendor/github.com/ethereum/go-ethereum/cmd/puppeth/wizard_netstats.go
new file mode 100644
index 00000000..99ca11bb
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/cmd/puppeth/wizard_netstats.go
@@ -0,0 +1,292 @@
+// Copyright 2017 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// go-ethereum is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with go-ethereum. If not, see .
+
+package main
+
+import (
+ "encoding/json"
+ "os"
+ "sort"
+ "strings"
+ "sync"
+
+ "github.com/ethereum/go-ethereum/core"
+ "github.com/ethereum/go-ethereum/log"
+ "github.com/olekukonko/tablewriter"
+)
+
+// networkStats verifies the status of network components and generates a protip
+// configuration set to give users hints on how to do various tasks.
+func (w *wizard) networkStats() {
+ if len(w.servers) == 0 {
+ log.Info("No remote machines to gather stats from")
+ return
+ }
+ // Clear out some previous configs to refill from current scan
+ w.conf.ethstats = ""
+ w.conf.bootnodes = w.conf.bootnodes[:0]
+
+ // Iterate over all the specified hosts and check their status
+ var pend sync.WaitGroup
+
+ stats := make(serverStats)
+ for server, pubkey := range w.conf.Servers {
+ pend.Add(1)
+
+ // Gather the service stats for each server concurrently
+ go func(server string, pubkey []byte) {
+ defer pend.Done()
+
+ stat := w.gatherStats(server, pubkey, w.servers[server])
+
+ // All status checks complete, report and check next server
+ w.lock.Lock()
+ defer w.lock.Unlock()
+
+ delete(w.services, server)
+ for service := range stat.services {
+ w.services[server] = append(w.services[server], service)
+ }
+ stats[server] = stat
+ }(server, pubkey)
+ }
+ pend.Wait()
+
+ // Print any collected stats and return
+ stats.render()
+}
+
+// gatherStats gathers service statistics for a particular remote server.
+func (w *wizard) gatherStats(server string, pubkey []byte, client *sshClient) *serverStat {
+ // Gather some global stats to feed into the wizard
+ var (
+ genesis string
+ ethstats string
+ bootnodes []string
+ )
+ // Ensure a valid SSH connection to the remote server
+ logger := log.New("server", server)
+ logger.Info("Starting remote server health-check")
+
+ stat := &serverStat{
+ services: make(map[string]map[string]string),
+ }
+ if client == nil {
+ conn, err := dial(server, pubkey)
+ if err != nil {
+ logger.Error("Failed to establish remote connection", "err", err)
+ stat.failure = err.Error()
+ return stat
+ }
+ client = conn
+ }
+ stat.address = client.address
+
+ // Client connected one way or another, run health-checks
+ logger.Debug("Checking for nginx availability")
+ if infos, err := checkNginx(client, w.network); err != nil {
+ if err != ErrServiceUnknown {
+ stat.services["nginx"] = map[string]string{"offline": err.Error()}
+ }
+ } else {
+ stat.services["nginx"] = infos.Report()
+ }
+ logger.Debug("Checking for ethstats availability")
+ if infos, err := checkEthstats(client, w.network); err != nil {
+ if err != ErrServiceUnknown {
+ stat.services["ethstats"] = map[string]string{"offline": err.Error()}
+ }
+ } else {
+ stat.services["ethstats"] = infos.Report()
+ ethstats = infos.config
+ }
+ logger.Debug("Checking for bootnode availability")
+ if infos, err := checkNode(client, w.network, true); err != nil {
+ if err != ErrServiceUnknown {
+ stat.services["bootnode"] = map[string]string{"offline": err.Error()}
+ }
+ } else {
+ stat.services["bootnode"] = infos.Report()
+
+ genesis = string(infos.genesis)
+ bootnodes = append(bootnodes, infos.enode)
+ }
+ logger.Debug("Checking for sealnode availability")
+ if infos, err := checkNode(client, w.network, false); err != nil {
+ if err != ErrServiceUnknown {
+ stat.services["sealnode"] = map[string]string{"offline": err.Error()}
+ }
+ } else {
+ stat.services["sealnode"] = infos.Report()
+ genesis = string(infos.genesis)
+ }
+ logger.Debug("Checking for explorer availability")
+ if infos, err := checkExplorer(client, w.network); err != nil {
+ if err != ErrServiceUnknown {
+ stat.services["explorer"] = map[string]string{"offline": err.Error()}
+ }
+ } else {
+ stat.services["explorer"] = infos.Report()
+ }
+ logger.Debug("Checking for wallet availability")
+ if infos, err := checkWallet(client, w.network); err != nil {
+ if err != ErrServiceUnknown {
+ stat.services["wallet"] = map[string]string{"offline": err.Error()}
+ }
+ } else {
+ stat.services["wallet"] = infos.Report()
+ }
+ logger.Debug("Checking for faucet availability")
+ if infos, err := checkFaucet(client, w.network); err != nil {
+ if err != ErrServiceUnknown {
+ stat.services["faucet"] = map[string]string{"offline": err.Error()}
+ }
+ } else {
+ stat.services["faucet"] = infos.Report()
+ }
+ logger.Debug("Checking for dashboard availability")
+ if infos, err := checkDashboard(client, w.network); err != nil {
+ if err != ErrServiceUnknown {
+ stat.services["dashboard"] = map[string]string{"offline": err.Error()}
+ }
+ } else {
+ stat.services["dashboard"] = infos.Report()
+ }
+ // Feed and newly discovered information into the wizard
+ w.lock.Lock()
+ defer w.lock.Unlock()
+
+ if genesis != "" && w.conf.Genesis == nil {
+ g := new(core.Genesis)
+ if err := json.Unmarshal([]byte(genesis), g); err != nil {
+ log.Error("Failed to parse remote genesis", "err", err)
+ } else {
+ w.conf.Genesis = g
+ }
+ }
+ if ethstats != "" {
+ w.conf.ethstats = ethstats
+ }
+ w.conf.bootnodes = append(w.conf.bootnodes, bootnodes...)
+
+ return stat
+}
+
+// serverStat is a collection of service configuration parameters and health
+// check reports to print to the user.
+type serverStat struct {
+ address string
+ failure string
+ services map[string]map[string]string
+}
+
+// serverStats is a collection of server stats for multiple hosts.
+type serverStats map[string]*serverStat
+
+// render converts the gathered statistics into a user friendly tabular report
+// and prints it to the standard output.
+func (stats serverStats) render() {
+ // Start gathering service statistics and config parameters
+ table := tablewriter.NewWriter(os.Stdout)
+
+ table.SetHeader([]string{"Server", "Address", "Service", "Config", "Value"})
+ table.SetAlignment(tablewriter.ALIGN_LEFT)
+ table.SetColWidth(40)
+
+ // Find the longest lines for all columns for the hacked separator
+ separator := make([]string, 5)
+ for server, stat := range stats {
+ if len(server) > len(separator[0]) {
+ separator[0] = strings.Repeat("-", len(server))
+ }
+ if len(stat.address) > len(separator[1]) {
+ separator[1] = strings.Repeat("-", len(stat.address))
+ }
+ if len(stat.failure) > len(separator[1]) {
+ separator[1] = strings.Repeat("-", len(stat.failure))
+ }
+ for service, configs := range stat.services {
+ if len(service) > len(separator[2]) {
+ separator[2] = strings.Repeat("-", len(service))
+ }
+ for config, value := range configs {
+ if len(config) > len(separator[3]) {
+ separator[3] = strings.Repeat("-", len(config))
+ }
+ for _, val := range strings.Split(value, "\n") {
+ if len(val) > len(separator[4]) {
+ separator[4] = strings.Repeat("-", len(val))
+ }
+ }
+ }
+ }
+ }
+ // Fill up the server report in alphabetical order
+ servers := make([]string, 0, len(stats))
+ for server := range stats {
+ servers = append(servers, server)
+ }
+ sort.Strings(servers)
+
+ for i, server := range servers {
+ // Add a separator between all servers
+ if i > 0 {
+ table.Append(separator)
+ }
+ // Fill up the service report in alphabetical order
+ services := make([]string, 0, len(stats[server].services))
+ for service := range stats[server].services {
+ services = append(services, service)
+ }
+ sort.Strings(services)
+
+ if len(services) == 0 {
+ if stats[server].failure != "" {
+ table.Append([]string{server, stats[server].failure, "", "", ""})
+ } else {
+ table.Append([]string{server, stats[server].address, "", "", ""})
+ }
+ }
+ for j, service := range services {
+ // Add an empty line between all services
+ if j > 0 {
+ table.Append([]string{"", "", "", separator[3], separator[4]})
+ }
+ // Fill up the config report in alphabetical order
+ configs := make([]string, 0, len(stats[server].services[service]))
+ for service := range stats[server].services[service] {
+ configs = append(configs, service)
+ }
+ sort.Strings(configs)
+
+ for k, config := range configs {
+ for l, value := range strings.Split(stats[server].services[service][config], "\n") {
+ switch {
+ case j == 0 && k == 0 && l == 0:
+ table.Append([]string{server, stats[server].address, service, config, value})
+ case k == 0 && l == 0:
+ table.Append([]string{"", "", service, config, value})
+ case l == 0:
+ table.Append([]string{"", "", "", config, value})
+ default:
+ table.Append([]string{"", "", "", "", value})
+ }
+ }
+ }
+ }
+ }
+ table.Render()
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/puppeth/wizard_network.go b/vendor/github.com/ethereum/go-ethereum/cmd/puppeth/wizard_network.go
new file mode 100644
index 00000000..83b10cf3
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/cmd/puppeth/wizard_network.go
@@ -0,0 +1,200 @@
+// Copyright 2017 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// go-ethereum is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with go-ethereum. If not, see .
+
+package main
+
+import (
+ "fmt"
+ "strings"
+
+ "github.com/ethereum/go-ethereum/log"
+)
+
+// manageServers displays a list of servers the user can disconnect from, and an
+// option to connect to new servers.
+func (w *wizard) manageServers() {
+ // List all the servers we can disconnect, along with an entry to connect a new one
+ fmt.Println()
+
+ servers := w.conf.servers()
+ for i, server := range servers {
+ fmt.Printf(" %d. Disconnect %s\n", i+1, server)
+ }
+ fmt.Printf(" %d. Connect another server\n", len(w.conf.Servers)+1)
+
+ choice := w.readInt()
+ if choice < 0 || choice > len(w.conf.Servers)+1 {
+ log.Error("Invalid server choice, aborting")
+ return
+ }
+ // If the user selected an existing server, drop it
+ if choice <= len(w.conf.Servers) {
+ server := servers[choice-1]
+ client := w.servers[server]
+
+ delete(w.servers, server)
+ if client != nil {
+ client.Close()
+ }
+ delete(w.conf.Servers, server)
+ w.conf.flush()
+
+ log.Info("Disconnected existing server", "server", server)
+ w.networkStats()
+ return
+ }
+ // If the user requested connecting a new server, do it
+ if w.makeServer() != "" {
+ w.networkStats()
+ }
+}
+
+// makeServer reads a single line from stdin and interprets it as
+// username:identity@hostname to connect to. It tries to establish a
+// new SSH session and also executing some baseline validations.
+//
+// If connection succeeds, the server is added to the wizards configs!
+func (w *wizard) makeServer() string {
+ fmt.Println()
+ fmt.Println("What is the remote server's address ([username[:identity]@]hostname[:port])?")
+
+ // Read and dial the server to ensure docker is present
+ input := w.readString()
+
+ client, err := dial(input, nil)
+ if err != nil {
+ log.Error("Server not ready for puppeth", "err", err)
+ return ""
+ }
+ // All checks passed, start tracking the server
+ w.servers[input] = client
+ w.conf.Servers[input] = client.pubkey
+ w.conf.flush()
+
+ return input
+}
+
+// selectServer lists the user all the currently known servers to choose from,
+// also granting the option to add a new one.
+func (w *wizard) selectServer() string {
+ // List the available server to the user and wait for a choice
+ fmt.Println()
+ fmt.Println("Which server do you want to interact with?")
+
+ servers := w.conf.servers()
+ for i, server := range servers {
+ fmt.Printf(" %d. %s\n", i+1, server)
+ }
+ fmt.Printf(" %d. Connect another server\n", len(w.conf.Servers)+1)
+
+ choice := w.readInt()
+ if choice < 0 || choice > len(w.conf.Servers)+1 {
+ log.Error("Invalid server choice, aborting")
+ return ""
+ }
+ // If the user requested connecting to a new server, go for it
+ if choice <= len(w.conf.Servers) {
+ return servers[choice-1]
+ }
+ return w.makeServer()
+}
+
+// manageComponents displays a list of network components the user can tear down
+// and an option
+func (w *wizard) manageComponents() {
+ // List all the components we can tear down, along with an entry to deploy a new one
+ fmt.Println()
+
+ var serviceHosts, serviceNames []string
+ for server, services := range w.services {
+ for _, service := range services {
+ serviceHosts = append(serviceHosts, server)
+ serviceNames = append(serviceNames, service)
+
+ fmt.Printf(" %d. Tear down %s on %s\n", len(serviceHosts), strings.Title(service), server)
+ }
+ }
+ fmt.Printf(" %d. Deploy new network component\n", len(serviceHosts)+1)
+
+ choice := w.readInt()
+ if choice < 0 || choice > len(serviceHosts)+1 {
+ log.Error("Invalid component choice, aborting")
+ return
+ }
+ // If the user selected an existing service, destroy it
+ if choice <= len(serviceHosts) {
+ // Figure out the service to destroy and execute it
+ service := serviceNames[choice-1]
+ server := serviceHosts[choice-1]
+ client := w.servers[server]
+
+ if out, err := tearDown(client, w.network, service, true); err != nil {
+ log.Error("Failed to tear down component", "err", err)
+ if len(out) > 0 {
+ fmt.Printf("%s\n", out)
+ }
+ return
+ }
+ // Clean up any references to it from out state
+ services := w.services[server]
+ for i, name := range services {
+ if name == service {
+ w.services[server] = append(services[:i], services[i+1:]...)
+ if len(w.services[server]) == 0 {
+ delete(w.services, server)
+ }
+ }
+ }
+ log.Info("Torn down existing component", "server", server, "service", service)
+ return
+ }
+ // If the user requested deploying a new component, do it
+ w.deployComponent()
+}
+
+// deployComponent displays a list of network components the user can deploy and
+// guides through the process.
+func (w *wizard) deployComponent() {
+ // Print all the things we can deploy and wait or user choice
+ fmt.Println()
+ fmt.Println("What would you like to deploy? (recommended order)")
+ fmt.Println(" 1. Ethstats - Network monitoring tool")
+ fmt.Println(" 2. Bootnode - Entry point of the network")
+ fmt.Println(" 3. Sealer - Full node minting new blocks")
+ fmt.Println(" 4. Explorer - Chain analysis webservice (ethash only)")
+ fmt.Println(" 5. Wallet - Browser wallet for quick sends")
+ fmt.Println(" 6. Faucet - Crypto faucet to give away funds")
+ fmt.Println(" 7. Dashboard - Website listing above web-services")
+
+ switch w.read() {
+ case "1":
+ w.deployEthstats()
+ case "2":
+ w.deployNode(true)
+ case "3":
+ w.deployNode(false)
+ case "4":
+ w.deployExplorer()
+ case "5":
+ w.deployWallet()
+ case "6":
+ w.deployFaucet()
+ case "7":
+ w.deployDashboard()
+ default:
+ log.Error("That's not something I can do")
+ }
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/puppeth/wizard_nginx.go b/vendor/github.com/ethereum/go-ethereum/cmd/puppeth/wizard_nginx.go
new file mode 100644
index 00000000..8397b7fd
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/cmd/puppeth/wizard_nginx.go
@@ -0,0 +1,65 @@
+// Copyright 2017 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// go-ethereum is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with go-ethereum. If not, see .
+
+package main
+
+import (
+ "fmt"
+
+ "github.com/ethereum/go-ethereum/log"
+)
+
+// ensureVirtualHost checks whether a reverse-proxy is running on the specified
+// host machine, and if yes requests a virtual host from the user to host a
+// specific web service on. If no proxy exists, the method will offer to deploy
+// one.
+//
+// If the user elects not to use a reverse proxy, an empty hostname is returned!
+func (w *wizard) ensureVirtualHost(client *sshClient, port int, def string) (string, error) {
+ proxy, _ := checkNginx(client, w.network)
+ if proxy != nil {
+ // Reverse proxy is running, if ports match, we need a virtual host
+ if proxy.port == port {
+ fmt.Println()
+ fmt.Printf("Shared port, which domain to assign? (default = %s)\n", def)
+ return w.readDefaultString(def), nil
+ }
+ }
+ // Reverse proxy is not running, offer to deploy a new one
+ fmt.Println()
+ fmt.Println("Allow sharing the port with other services (y/n)? (default = yes)")
+ if w.readDefaultYesNo(true) {
+ nocache := false
+ if proxy != nil {
+ fmt.Println()
+ fmt.Printf("Should the reverse-proxy be rebuilt from scratch (y/n)? (default = no)\n")
+ nocache = w.readDefaultYesNo(false)
+ }
+ if out, err := deployNginx(client, w.network, port, nocache); err != nil {
+ log.Error("Failed to deploy reverse-proxy", "err", err)
+ if len(out) > 0 {
+ fmt.Printf("%s\n", out)
+ }
+ return "", err
+ }
+ // Reverse proxy deployed, ask again for the virtual-host
+ fmt.Println()
+ fmt.Printf("Proxy deployed, which domain to assign? (default = %s)\n", def)
+ return w.readDefaultString(def), nil
+ }
+ // Reverse proxy not requested, deploy as a standalone service
+ return "", nil
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/puppeth/wizard_node.go b/vendor/github.com/ethereum/go-ethereum/cmd/puppeth/wizard_node.go
new file mode 100644
index 00000000..e37297f6
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/cmd/puppeth/wizard_node.go
@@ -0,0 +1,182 @@
+// Copyright 2017 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// go-ethereum is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with go-ethereum. If not, see .
+
+package main
+
+import (
+ "encoding/json"
+ "fmt"
+ "time"
+
+ "github.com/ethereum/go-ethereum/accounts/keystore"
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/log"
+)
+
+// deployNode creates a new node configuration based on some user input.
+func (w *wizard) deployNode(boot bool) {
+ // Do some sanity check before the user wastes time on input
+ if w.conf.Genesis == nil {
+ log.Error("No genesis block configured")
+ return
+ }
+ if w.conf.ethstats == "" {
+ log.Error("No ethstats server configured")
+ return
+ }
+ // Select the server to interact with
+ server := w.selectServer()
+ if server == "" {
+ return
+ }
+ client := w.servers[server]
+
+ // Retrieve any active node configurations from the server
+ infos, err := checkNode(client, w.network, boot)
+ if err != nil {
+ if boot {
+ infos = &nodeInfos{port: 30303, peersTotal: 512, peersLight: 256}
+ } else {
+ infos = &nodeInfos{port: 30303, peersTotal: 50, peersLight: 0, gasTarget: 7.5, gasLimit: 10, gasPrice: 1}
+ }
+ }
+ existed := err == nil
+
+ infos.genesis, _ = json.MarshalIndent(w.conf.Genesis, "", " ")
+ infos.network = w.conf.Genesis.Config.ChainID.Int64()
+
+ // Figure out where the user wants to store the persistent data
+ fmt.Println()
+ if infos.datadir == "" {
+ fmt.Printf("Where should data be stored on the remote machine?\n")
+ infos.datadir = w.readString()
+ } else {
+ fmt.Printf("Where should data be stored on the remote machine? (default = %s)\n", infos.datadir)
+ infos.datadir = w.readDefaultString(infos.datadir)
+ }
+ if w.conf.Genesis.Config.Ethash != nil && !boot {
+ fmt.Println()
+ if infos.ethashdir == "" {
+ fmt.Printf("Where should the ethash mining DAGs be stored on the remote machine?\n")
+ infos.ethashdir = w.readString()
+ } else {
+ fmt.Printf("Where should the ethash mining DAGs be stored on the remote machine? (default = %s)\n", infos.ethashdir)
+ infos.ethashdir = w.readDefaultString(infos.ethashdir)
+ }
+ }
+ // Figure out which port to listen on
+ fmt.Println()
+ fmt.Printf("Which TCP/UDP port to listen on? (default = %d)\n", infos.port)
+ infos.port = w.readDefaultInt(infos.port)
+
+ // Figure out how many peers to allow (different based on node type)
+ fmt.Println()
+ fmt.Printf("How many peers to allow connecting? (default = %d)\n", infos.peersTotal)
+ infos.peersTotal = w.readDefaultInt(infos.peersTotal)
+
+ // Figure out how many light peers to allow (different based on node type)
+ fmt.Println()
+ fmt.Printf("How many light peers to allow connecting? (default = %d)\n", infos.peersLight)
+ infos.peersLight = w.readDefaultInt(infos.peersLight)
+
+ // Set a proper name to report on the stats page
+ fmt.Println()
+ if infos.ethstats == "" {
+ fmt.Printf("What should the node be called on the stats page?\n")
+ infos.ethstats = w.readString() + ":" + w.conf.ethstats
+ } else {
+ fmt.Printf("What should the node be called on the stats page? (default = %s)\n", infos.ethstats)
+ infos.ethstats = w.readDefaultString(infos.ethstats) + ":" + w.conf.ethstats
+ }
+ // If the node is a miner/signer, load up needed credentials
+ if !boot {
+ if w.conf.Genesis.Config.Ethash != nil {
+ // Ethash based miners only need an etherbase to mine against
+ fmt.Println()
+ if infos.etherbase == "" {
+ fmt.Printf("What address should the miner use?\n")
+ for {
+ if address := w.readAddress(); address != nil {
+ infos.etherbase = address.Hex()
+ break
+ }
+ }
+ } else {
+ fmt.Printf("What address should the miner use? (default = %s)\n", infos.etherbase)
+ infos.etherbase = w.readDefaultAddress(common.HexToAddress(infos.etherbase)).Hex()
+ }
+ } else if w.conf.Genesis.Config.Clique != nil {
+ // If a previous signer was already set, offer to reuse it
+ if infos.keyJSON != "" {
+ if key, err := keystore.DecryptKey([]byte(infos.keyJSON), infos.keyPass); err != nil {
+ infos.keyJSON, infos.keyPass = "", ""
+ } else {
+ fmt.Println()
+ fmt.Printf("Reuse previous (%s) signing account (y/n)? (default = yes)\n", key.Address.Hex())
+ if !w.readDefaultYesNo(true) {
+ infos.keyJSON, infos.keyPass = "", ""
+ }
+ }
+ }
+ // Clique based signers need a keyfile and unlock password, ask if unavailable
+ if infos.keyJSON == "" {
+ fmt.Println()
+ fmt.Println("Please paste the signer's key JSON:")
+ infos.keyJSON = w.readJSON()
+
+ fmt.Println()
+ fmt.Println("What's the unlock password for the account? (won't be echoed)")
+ infos.keyPass = w.readPassword()
+
+ if _, err := keystore.DecryptKey([]byte(infos.keyJSON), infos.keyPass); err != nil {
+ log.Error("Failed to decrypt key with given passphrase")
+ return
+ }
+ }
+ }
+ // Establish the gas dynamics to be enforced by the signer
+ fmt.Println()
+ fmt.Printf("What gas limit should empty blocks target (MGas)? (default = %0.3f)\n", infos.gasTarget)
+ infos.gasTarget = w.readDefaultFloat(infos.gasTarget)
+
+ fmt.Println()
+ fmt.Printf("What gas limit should full blocks target (MGas)? (default = %0.3f)\n", infos.gasLimit)
+ infos.gasLimit = w.readDefaultFloat(infos.gasLimit)
+
+ fmt.Println()
+ fmt.Printf("What gas price should the signer require (GWei)? (default = %0.3f)\n", infos.gasPrice)
+ infos.gasPrice = w.readDefaultFloat(infos.gasPrice)
+ }
+ // Try to deploy the full node on the host
+ nocache := false
+ if existed {
+ fmt.Println()
+ fmt.Printf("Should the node be built from scratch (y/n)? (default = no)\n")
+ nocache = w.readDefaultYesNo(false)
+ }
+ if out, err := deployNode(client, w.network, w.conf.bootnodes, infos, nocache); err != nil {
+ log.Error("Failed to deploy Ethereum node container", "err", err)
+ if len(out) > 0 {
+ fmt.Printf("%s\n", out)
+ }
+ return
+ }
+ // All ok, run a network scan to pick any changes up
+ log.Info("Waiting for node to finish booting")
+ time.Sleep(3 * time.Second)
+
+ w.networkStats()
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/puppeth/wizard_wallet.go b/vendor/github.com/ethereum/go-ethereum/cmd/puppeth/wizard_wallet.go
new file mode 100644
index 00000000..ca1ea5bd
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/cmd/puppeth/wizard_wallet.go
@@ -0,0 +1,113 @@
+// Copyright 2017 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// go-ethereum is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with go-ethereum. If not, see .
+
+package main
+
+import (
+ "encoding/json"
+ "fmt"
+ "time"
+
+ "github.com/ethereum/go-ethereum/log"
+)
+
+// deployWallet creates a new web wallet based on some user input.
+func (w *wizard) deployWallet() {
+ // Do some sanity check before the user wastes time on input
+ if w.conf.Genesis == nil {
+ log.Error("No genesis block configured")
+ return
+ }
+ if w.conf.ethstats == "" {
+ log.Error("No ethstats server configured")
+ return
+ }
+ // Select the server to interact with
+ server := w.selectServer()
+ if server == "" {
+ return
+ }
+ client := w.servers[server]
+
+ // Retrieve any active node configurations from the server
+ infos, err := checkWallet(client, w.network)
+ if err != nil {
+ infos = &walletInfos{
+ nodePort: 30303, rpcPort: 8545, webPort: 80, webHost: client.server,
+ }
+ }
+ existed := err == nil
+
+ infos.genesis, _ = json.MarshalIndent(w.conf.Genesis, "", " ")
+ infos.network = w.conf.Genesis.Config.ChainID.Int64()
+
+ // Figure out which port to listen on
+ fmt.Println()
+ fmt.Printf("Which port should the wallet listen on? (default = %d)\n", infos.webPort)
+ infos.webPort = w.readDefaultInt(infos.webPort)
+
+ // Figure which virtual-host to deploy ethstats on
+ if infos.webHost, err = w.ensureVirtualHost(client, infos.webPort, infos.webHost); err != nil {
+ log.Error("Failed to decide on wallet host", "err", err)
+ return
+ }
+ // Figure out where the user wants to store the persistent data
+ fmt.Println()
+ if infos.datadir == "" {
+ fmt.Printf("Where should data be stored on the remote machine?\n")
+ infos.datadir = w.readString()
+ } else {
+ fmt.Printf("Where should data be stored on the remote machine? (default = %s)\n", infos.datadir)
+ infos.datadir = w.readDefaultString(infos.datadir)
+ }
+ // Figure out which port to listen on
+ fmt.Println()
+ fmt.Printf("Which TCP/UDP port should the backing node listen on? (default = %d)\n", infos.nodePort)
+ infos.nodePort = w.readDefaultInt(infos.nodePort)
+
+ fmt.Println()
+ fmt.Printf("Which port should the backing RPC API listen on? (default = %d)\n", infos.rpcPort)
+ infos.rpcPort = w.readDefaultInt(infos.rpcPort)
+
+ // Set a proper name to report on the stats page
+ fmt.Println()
+ if infos.ethstats == "" {
+ fmt.Printf("What should the wallet be called on the stats page?\n")
+ infos.ethstats = w.readString() + ":" + w.conf.ethstats
+ } else {
+ fmt.Printf("What should the wallet be called on the stats page? (default = %s)\n", infos.ethstats)
+ infos.ethstats = w.readDefaultString(infos.ethstats) + ":" + w.conf.ethstats
+ }
+ // Try to deploy the wallet on the host
+ nocache := false
+ if existed {
+ fmt.Println()
+ fmt.Printf("Should the wallet be built from scratch (y/n)? (default = no)\n")
+ nocache = w.readDefaultYesNo(false)
+ }
+ if out, err := deployWallet(client, w.network, w.conf.bootnodes, infos, nocache); err != nil {
+ log.Error("Failed to deploy wallet container", "err", err)
+ if len(out) > 0 {
+ fmt.Printf("%s\n", out)
+ }
+ return
+ }
+ // All ok, run a network scan to pick any changes up
+ log.Info("Waiting for node to finish booting")
+ time.Sleep(3 * time.Second)
+
+ w.networkStats()
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/rlpdump/main.go b/vendor/github.com/ethereum/go-ethereum/cmd/rlpdump/main.go
new file mode 100644
index 00000000..d0f993c5
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/cmd/rlpdump/main.go
@@ -0,0 +1,147 @@
+// Copyright 2015 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// go-ethereum is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with go-ethereum. If not, see .
+
+// rlpdump is a pretty-printer for RLP data.
+package main
+
+import (
+ "bytes"
+ "encoding/hex"
+ "flag"
+ "fmt"
+ "io"
+ "os"
+ "strings"
+
+ "github.com/ethereum/go-ethereum/rlp"
+)
+
+var (
+ hexMode = flag.String("hex", "", "dump given hex data")
+ noASCII = flag.Bool("noascii", false, "don't print ASCII strings readably")
+ single = flag.Bool("single", false, "print only the first element, discard the rest")
+)
+
+func init() {
+ flag.Usage = func() {
+ fmt.Fprintln(os.Stderr, "Usage:", os.Args[0], "[-noascii] [-hex ] [filename]")
+ flag.PrintDefaults()
+ fmt.Fprintln(os.Stderr, `
+Dumps RLP data from the given file in readable form.
+If the filename is omitted, data is read from stdin.`)
+ }
+}
+
+func main() {
+ flag.Parse()
+
+ var r io.Reader
+ switch {
+ case *hexMode != "":
+ data, err := hex.DecodeString(strings.TrimPrefix(*hexMode, "0x"))
+ if err != nil {
+ die(err)
+ }
+ r = bytes.NewReader(data)
+
+ case flag.NArg() == 0:
+ r = os.Stdin
+
+ case flag.NArg() == 1:
+ fd, err := os.Open(flag.Arg(0))
+ if err != nil {
+ die(err)
+ }
+ defer fd.Close()
+ r = fd
+
+ default:
+ fmt.Fprintln(os.Stderr, "Error: too many arguments")
+ flag.Usage()
+ os.Exit(2)
+ }
+
+ s := rlp.NewStream(r, 0)
+ for {
+ if err := dump(s, 0); err != nil {
+ if err != io.EOF {
+ die(err)
+ }
+ break
+ }
+ fmt.Println()
+ if *single {
+ break
+ }
+ }
+}
+
+func dump(s *rlp.Stream, depth int) error {
+ kind, size, err := s.Kind()
+ if err != nil {
+ return err
+ }
+ switch kind {
+ case rlp.Byte, rlp.String:
+ str, err := s.Bytes()
+ if err != nil {
+ return err
+ }
+ if len(str) == 0 || !*noASCII && isASCII(str) {
+ fmt.Printf("%s%q", ws(depth), str)
+ } else {
+ fmt.Printf("%s%x", ws(depth), str)
+ }
+ case rlp.List:
+ s.List()
+ defer s.ListEnd()
+ if size == 0 {
+ fmt.Print(ws(depth) + "[]")
+ } else {
+ fmt.Println(ws(depth) + "[")
+ for i := 0; ; i++ {
+ if i > 0 {
+ fmt.Print(",\n")
+ }
+ if err := dump(s, depth+1); err == rlp.EOL {
+ break
+ } else if err != nil {
+ return err
+ }
+ }
+ fmt.Print(ws(depth) + "]")
+ }
+ }
+ return nil
+}
+
+func isASCII(b []byte) bool {
+ for _, c := range b {
+ if c < 32 || c > 126 {
+ return false
+ }
+ }
+ return true
+}
+
+func ws(n int) string {
+ return strings.Repeat(" ", n)
+}
+
+func die(args ...interface{}) {
+ fmt.Fprintln(os.Stderr, args...)
+ os.Exit(1)
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/swarm/access.go b/vendor/github.com/ethereum/go-ethereum/cmd/swarm/access.go
new file mode 100644
index 00000000..cc0cc820
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/cmd/swarm/access.go
@@ -0,0 +1,297 @@
+// Copyright 2018 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// go-ethereum is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with go-ethereum. If not, see .
+package main
+
+import (
+ "crypto/rand"
+ "encoding/json"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "strings"
+
+ "github.com/ethereum/go-ethereum/cmd/utils"
+ "github.com/ethereum/go-ethereum/swarm/api"
+ "github.com/ethereum/go-ethereum/swarm/api/client"
+ "gopkg.in/urfave/cli.v1"
+)
+
+var (
+ salt = make([]byte, 32)
+ accessCommand = cli.Command{
+ CustomHelpTemplate: helpTemplate,
+ Name: "access",
+ Usage: "encrypts a reference and embeds it into a root manifest",
+ ArgsUsage: "[",
+ Description: "encrypts a reference and embeds it into a root manifest",
+ Subcommands: []cli.Command{
+ {
+ CustomHelpTemplate: helpTemplate,
+ Name: "new",
+ Usage: "encrypts a reference and embeds it into a root manifest",
+ ArgsUsage: "][",
+ Description: "encrypts a reference and embeds it into a root access manifest and prints the resulting manifest",
+ Subcommands: []cli.Command{
+ {
+ Action: accessNewPass,
+ CustomHelpTemplate: helpTemplate,
+ Flags: []cli.Flag{
+ utils.PasswordFileFlag,
+ SwarmDryRunFlag,
+ },
+ Name: "pass",
+ Usage: "encrypts a reference with a password and embeds it into a root manifest",
+ ArgsUsage: "][",
+ Description: "encrypts a reference and embeds it into a root access manifest and prints the resulting manifest",
+ },
+ {
+ Action: accessNewPK,
+ CustomHelpTemplate: helpTemplate,
+ Flags: []cli.Flag{
+ utils.PasswordFileFlag,
+ SwarmDryRunFlag,
+ SwarmAccessGrantKeyFlag,
+ },
+ Name: "pk",
+ Usage: "encrypts a reference with the node's private key and a given grantee's public key and embeds it into a root manifest",
+ ArgsUsage: "][",
+ Description: "encrypts a reference and embeds it into a root access manifest and prints the resulting manifest",
+ },
+ {
+ Action: accessNewACT,
+ CustomHelpTemplate: helpTemplate,
+ Flags: []cli.Flag{
+ SwarmAccessGrantKeysFlag,
+ SwarmDryRunFlag,
+ utils.PasswordFileFlag,
+ },
+ Name: "act",
+ Usage: "encrypts a reference with the node's private key and a given grantee's public key and embeds it into a root manifest",
+ ArgsUsage: "][",
+ Description: "encrypts a reference and embeds it into a root access manifest and prints the resulting manifest",
+ },
+ },
+ },
+ },
+ }
+)
+
+func init() {
+ if _, err := io.ReadFull(rand.Reader, salt); err != nil {
+ panic("reading from crypto/rand failed: " + err.Error())
+ }
+}
+
+func accessNewPass(ctx *cli.Context) {
+ args := ctx.Args()
+ if len(args) != 1 {
+ utils.Fatalf("Expected 1 argument - the ref")
+ }
+
+ var (
+ ae *api.AccessEntry
+ accessKey []byte
+ err error
+ ref = args[0]
+ password = getPassPhrase("", 0, makePasswordList(ctx))
+ dryRun = ctx.Bool(SwarmDryRunFlag.Name)
+ )
+ accessKey, ae, err = api.DoPassword(ctx, password, salt)
+ if err != nil {
+ utils.Fatalf("error getting session key: %v", err)
+ }
+ m, err := api.GenerateAccessControlManifest(ctx, ref, accessKey, ae)
+ if err != nil {
+ utils.Fatalf("had an error generating the manifest: %v", err)
+ }
+ if dryRun {
+ err = printManifests(m, nil)
+ if err != nil {
+ utils.Fatalf("had an error printing the manifests: %v", err)
+ }
+ } else {
+ err = uploadManifests(ctx, m, nil)
+ if err != nil {
+ utils.Fatalf("had an error uploading the manifests: %v", err)
+ }
+ }
+}
+
+func accessNewPK(ctx *cli.Context) {
+ args := ctx.Args()
+ if len(args) != 1 {
+ utils.Fatalf("Expected 1 argument - the ref")
+ }
+
+ var (
+ ae *api.AccessEntry
+ sessionKey []byte
+ err error
+ ref = args[0]
+ privateKey = getPrivKey(ctx)
+ granteePublicKey = ctx.String(SwarmAccessGrantKeyFlag.Name)
+ dryRun = ctx.Bool(SwarmDryRunFlag.Name)
+ )
+ sessionKey, ae, err = api.DoPK(ctx, privateKey, granteePublicKey, salt)
+ if err != nil {
+ utils.Fatalf("error getting session key: %v", err)
+ }
+ m, err := api.GenerateAccessControlManifest(ctx, ref, sessionKey, ae)
+ if err != nil {
+ utils.Fatalf("had an error generating the manifest: %v", err)
+ }
+ if dryRun {
+ err = printManifests(m, nil)
+ if err != nil {
+ utils.Fatalf("had an error printing the manifests: %v", err)
+ }
+ } else {
+ err = uploadManifests(ctx, m, nil)
+ if err != nil {
+ utils.Fatalf("had an error uploading the manifests: %v", err)
+ }
+ }
+}
+
+func accessNewACT(ctx *cli.Context) {
+ args := ctx.Args()
+ if len(args) != 1 {
+ utils.Fatalf("Expected 1 argument - the ref")
+ }
+
+ var (
+ ae *api.AccessEntry
+ actManifest *api.Manifest
+ accessKey []byte
+ err error
+ ref = args[0]
+ pkGrantees []string
+ passGrantees []string
+ pkGranteesFilename = ctx.String(SwarmAccessGrantKeysFlag.Name)
+ passGranteesFilename = ctx.String(utils.PasswordFileFlag.Name)
+ privateKey = getPrivKey(ctx)
+ dryRun = ctx.Bool(SwarmDryRunFlag.Name)
+ )
+ if pkGranteesFilename == "" && passGranteesFilename == "" {
+ utils.Fatalf("you have to provide either a grantee public-keys file or an encryption passwords file (or both)")
+ }
+
+ if pkGranteesFilename != "" {
+ bytes, err := ioutil.ReadFile(pkGranteesFilename)
+ if err != nil {
+ utils.Fatalf("had an error reading the grantee public key list")
+ }
+ pkGrantees = strings.Split(strings.Trim(string(bytes), "\n"), "\n")
+ }
+
+ if passGranteesFilename != "" {
+ bytes, err := ioutil.ReadFile(passGranteesFilename)
+ if err != nil {
+ utils.Fatalf("could not read password filename: %v", err)
+ }
+ passGrantees = strings.Split(strings.Trim(string(bytes), "\n"), "\n")
+ }
+ accessKey, ae, actManifest, err = api.DoACT(ctx, privateKey, salt, pkGrantees, passGrantees)
+ if err != nil {
+ utils.Fatalf("error generating ACT manifest: %v", err)
+ }
+
+ if err != nil {
+ utils.Fatalf("error getting session key: %v", err)
+ }
+ m, err := api.GenerateAccessControlManifest(ctx, ref, accessKey, ae)
+ if err != nil {
+ utils.Fatalf("error generating root access manifest: %v", err)
+ }
+
+ if dryRun {
+ err = printManifests(m, actManifest)
+ if err != nil {
+ utils.Fatalf("had an error printing the manifests: %v", err)
+ }
+ } else {
+ err = uploadManifests(ctx, m, actManifest)
+ if err != nil {
+ utils.Fatalf("had an error uploading the manifests: %v", err)
+ }
+ }
+}
+
+func printManifests(rootAccessManifest, actManifest *api.Manifest) error {
+ js, err := json.Marshal(rootAccessManifest)
+ if err != nil {
+ return err
+ }
+ fmt.Println(string(js))
+
+ if actManifest != nil {
+ js, err := json.Marshal(actManifest)
+ if err != nil {
+ return err
+ }
+ fmt.Println(string(js))
+ }
+ return nil
+}
+
+func uploadManifests(ctx *cli.Context, rootAccessManifest, actManifest *api.Manifest) error {
+ bzzapi := strings.TrimRight(ctx.GlobalString(SwarmApiFlag.Name), "/")
+ client := client.NewClient(bzzapi)
+
+ var (
+ key string
+ err error
+ )
+ if actManifest != nil {
+ key, err = client.UploadManifest(actManifest, false)
+ if err != nil {
+ return err
+ }
+
+ rootAccessManifest.Entries[0].Access.Act = key
+ }
+ key, err = client.UploadManifest(rootAccessManifest, false)
+ if err != nil {
+ return err
+ }
+ fmt.Println(key)
+ return nil
+}
+
+// makePasswordList reads password lines from the file specified by the global --password flag
+// and also by the same subcommand --password flag.
+// This function ia a fork of utils.MakePasswordList to lookup cli context for subcommand.
+// Function ctx.SetGlobal is not setting the global flag value that can be accessed
+// by ctx.GlobalString using the current version of cli package.
+func makePasswordList(ctx *cli.Context) []string {
+ path := ctx.GlobalString(utils.PasswordFileFlag.Name)
+ if path == "" {
+ path = ctx.String(utils.PasswordFileFlag.Name)
+ if path == "" {
+ return nil
+ }
+ }
+ text, err := ioutil.ReadFile(path)
+ if err != nil {
+ utils.Fatalf("Failed to read password file: %v", err)
+ }
+ lines := strings.Split(string(text), "\n")
+ // Sanitise DOS line endings.
+ for i := range lines {
+ lines[i] = strings.TrimRight(lines[i], "\r")
+ }
+ return lines
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/swarm/bootnodes.go b/vendor/github.com/ethereum/go-ethereum/cmd/swarm/bootnodes.go
new file mode 100644
index 00000000..ce3cd528
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/cmd/swarm/bootnodes.go
@@ -0,0 +1,24 @@
+// Copyright 2018 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// go-ethereum is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with go-ethereum. If not, see .
+
+package main
+
+var SwarmBootnodes = []string{
+ // EF Swarm Bootnode - AWS - eu-central-1
+ "enode://4c113504601930bf2000c29bcd98d1716b6167749f58bad703bae338332fe93cc9d9204f08afb44100dc7bea479205f5d162df579f9a8f76f8b402d339709023@3.122.203.99:30301",
+ // EF Swarm Bootnode - AWS - us-west-2
+ "enode://89f2ede3371bff1ad9f2088f2012984e280287a4e2b68007c2a6ad994909c51886b4a8e9e2ecc97f9910aca538398e0a5804b0ee80a187fde1ba4f32626322ba@52.35.212.179:30301",
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/swarm/config.go b/vendor/github.com/ethereum/go-ethereum/cmd/swarm/config.go
new file mode 100644
index 00000000..32cd442a
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/cmd/swarm/config.go
@@ -0,0 +1,451 @@
+// Copyright 2017 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// go-ethereum is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with go-ethereum. If not, see .
+
+package main
+
+import (
+ "errors"
+ "fmt"
+ "io"
+ "os"
+ "reflect"
+ "strconv"
+ "strings"
+ "time"
+ "unicode"
+
+ cli "gopkg.in/urfave/cli.v1"
+
+ "github.com/ethereum/go-ethereum/cmd/utils"
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/log"
+ "github.com/ethereum/go-ethereum/node"
+ "github.com/naoina/toml"
+
+ bzzapi "github.com/ethereum/go-ethereum/swarm/api"
+)
+
+var (
+ //flag definition for the dumpconfig command
+ DumpConfigCommand = cli.Command{
+ Action: utils.MigrateFlags(dumpConfig),
+ Name: "dumpconfig",
+ Usage: "Show configuration values",
+ ArgsUsage: "",
+ Flags: app.Flags,
+ Category: "MISCELLANEOUS COMMANDS",
+ Description: `The dumpconfig command shows configuration values.`,
+ }
+
+ //flag definition for the config file command
+ SwarmTomlConfigPathFlag = cli.StringFlag{
+ Name: "config",
+ Usage: "TOML configuration file",
+ }
+)
+
+//constants for environment variables
+const (
+ SwarmEnvChequebookAddr = "SWARM_CHEQUEBOOK_ADDR"
+ SwarmEnvAccount = "SWARM_ACCOUNT"
+ SwarmEnvListenAddr = "SWARM_LISTEN_ADDR"
+ SwarmEnvPort = "SWARM_PORT"
+ SwarmEnvNetworkID = "SWARM_NETWORK_ID"
+ SwarmEnvSwapEnable = "SWARM_SWAP_ENABLE"
+ SwarmEnvSwapAPI = "SWARM_SWAP_API"
+ SwarmEnvSyncDisable = "SWARM_SYNC_DISABLE"
+ SwarmEnvSyncUpdateDelay = "SWARM_ENV_SYNC_UPDATE_DELAY"
+ SwarmEnvMaxStreamPeerServers = "SWARM_ENV_MAX_STREAM_PEER_SERVERS"
+ SwarmEnvLightNodeEnable = "SWARM_LIGHT_NODE_ENABLE"
+ SwarmEnvDeliverySkipCheck = "SWARM_DELIVERY_SKIP_CHECK"
+ SwarmEnvENSAPI = "SWARM_ENS_API"
+ SwarmEnvENSAddr = "SWARM_ENS_ADDR"
+ SwarmEnvCORS = "SWARM_CORS"
+ SwarmEnvBootnodes = "SWARM_BOOTNODES"
+ SwarmEnvPSSEnable = "SWARM_PSS_ENABLE"
+ SwarmEnvStorePath = "SWARM_STORE_PATH"
+ SwarmEnvStoreCapacity = "SWARM_STORE_CAPACITY"
+ SwarmEnvStoreCacheCapacity = "SWARM_STORE_CACHE_CAPACITY"
+ SwarmEnvBootnodeMode = "SWARM_BOOTNODE_MODE"
+ SwarmAccessPassword = "SWARM_ACCESS_PASSWORD"
+ SwarmAutoDefaultPath = "SWARM_AUTO_DEFAULTPATH"
+ SwarmGlobalstoreAPI = "SWARM_GLOBALSTORE_API"
+ GethEnvDataDir = "GETH_DATADIR"
+)
+
+// These settings ensure that TOML keys use the same names as Go struct fields.
+var tomlSettings = toml.Config{
+ NormFieldName: func(rt reflect.Type, key string) string {
+ return key
+ },
+ FieldToKey: func(rt reflect.Type, field string) string {
+ return field
+ },
+ MissingField: func(rt reflect.Type, field string) error {
+ link := ""
+ if unicode.IsUpper(rune(rt.Name()[0])) && rt.PkgPath() != "main" {
+ link = fmt.Sprintf(", check github.com/ethereum/go-ethereum/swarm/api/config.go for available fields")
+ }
+ return fmt.Errorf("field '%s' is not defined in %s%s", field, rt.String(), link)
+ },
+}
+
+//before booting the swarm node, build the configuration
+func buildConfig(ctx *cli.Context) (config *bzzapi.Config, err error) {
+ //start by creating a default config
+ config = bzzapi.NewConfig()
+ //first load settings from config file (if provided)
+ config, err = configFileOverride(config, ctx)
+ if err != nil {
+ return nil, err
+ }
+ //override settings provided by environment variables
+ config = envVarsOverride(config)
+ //override settings provided by command line
+ config = cmdLineOverride(config, ctx)
+ //validate configuration parameters
+ err = validateConfig(config)
+
+ return
+}
+
+//finally, after the configuration build phase is finished, initialize
+func initSwarmNode(config *bzzapi.Config, stack *node.Node, ctx *cli.Context, nodeconfig *node.Config) error {
+ //at this point, all vars should be set in the Config
+ //get the account for the provided swarm account
+ prvkey := getAccount(config.BzzAccount, ctx, stack)
+ //set the resolved config path (geth --datadir)
+ config.Path = expandPath(stack.InstanceDir())
+ //finally, initialize the configuration
+ err := config.Init(prvkey, nodeconfig.NodeKey())
+ if err != nil {
+ return err
+ }
+ //configuration phase completed here
+ log.Debug("Starting Swarm with the following parameters:")
+ //after having created the config, print it to screen
+ log.Debug(printConfig(config))
+ return nil
+}
+
+//configFileOverride overrides the current config with the config file, if a config file has been provided
+func configFileOverride(config *bzzapi.Config, ctx *cli.Context) (*bzzapi.Config, error) {
+ var err error
+
+ //only do something if the -config flag has been set
+ if ctx.GlobalIsSet(SwarmTomlConfigPathFlag.Name) {
+ var filepath string
+ if filepath = ctx.GlobalString(SwarmTomlConfigPathFlag.Name); filepath == "" {
+ utils.Fatalf("Config file flag provided with invalid file path")
+ }
+ var f *os.File
+ f, err = os.Open(filepath)
+ if err != nil {
+ return nil, err
+ }
+ defer f.Close()
+
+ //decode the TOML file into a Config struct
+ //note that we are decoding into the existing defaultConfig;
+ //if an entry is not present in the file, the default entry is kept
+ err = tomlSettings.NewDecoder(f).Decode(&config)
+ // Add file name to errors that have a line number.
+ if _, ok := err.(*toml.LineError); ok {
+ err = errors.New(filepath + ", " + err.Error())
+ }
+ }
+ return config, err
+}
+
+// cmdLineOverride overrides the current config with whatever is provided through the command line
+// most values are not allowed a zero value (empty string), if not otherwise noted
+func cmdLineOverride(currentConfig *bzzapi.Config, ctx *cli.Context) *bzzapi.Config {
+ if keyid := ctx.GlobalString(SwarmAccountFlag.Name); keyid != "" {
+ currentConfig.BzzAccount = keyid
+ }
+
+ if chbookaddr := ctx.GlobalString(ChequebookAddrFlag.Name); chbookaddr != "" {
+ currentConfig.Contract = common.HexToAddress(chbookaddr)
+ }
+
+ if networkid := ctx.GlobalString(SwarmNetworkIdFlag.Name); networkid != "" {
+ id, err := strconv.ParseUint(networkid, 10, 64)
+ if err != nil {
+ utils.Fatalf("invalid cli flag %s: %v", SwarmNetworkIdFlag.Name, err)
+ }
+ if id != 0 {
+ currentConfig.NetworkID = id
+ }
+ }
+
+ if ctx.GlobalIsSet(utils.DataDirFlag.Name) {
+ if datadir := ctx.GlobalString(utils.DataDirFlag.Name); datadir != "" {
+ currentConfig.Path = expandPath(datadir)
+ }
+ }
+
+ bzzport := ctx.GlobalString(SwarmPortFlag.Name)
+ if len(bzzport) > 0 {
+ currentConfig.Port = bzzport
+ }
+
+ if bzzaddr := ctx.GlobalString(SwarmListenAddrFlag.Name); bzzaddr != "" {
+ currentConfig.ListenAddr = bzzaddr
+ }
+
+ if ctx.GlobalIsSet(SwarmSwapEnabledFlag.Name) {
+ currentConfig.SwapEnabled = true
+ }
+
+ if ctx.GlobalIsSet(SwarmSyncDisabledFlag.Name) {
+ currentConfig.SyncEnabled = false
+ }
+
+ if d := ctx.GlobalDuration(SwarmSyncUpdateDelay.Name); d > 0 {
+ currentConfig.SyncUpdateDelay = d
+ }
+
+ // any value including 0 is acceptable
+ currentConfig.MaxStreamPeerServers = ctx.GlobalInt(SwarmMaxStreamPeerServersFlag.Name)
+
+ if ctx.GlobalIsSet(SwarmLightNodeEnabled.Name) {
+ currentConfig.LightNodeEnabled = true
+ }
+
+ if ctx.GlobalIsSet(SwarmDeliverySkipCheckFlag.Name) {
+ currentConfig.DeliverySkipCheck = true
+ }
+
+ currentConfig.SwapAPI = ctx.GlobalString(SwarmSwapAPIFlag.Name)
+ if currentConfig.SwapEnabled && currentConfig.SwapAPI == "" {
+ utils.Fatalf(SwarmErrSwapSetNoAPI)
+ }
+
+ if ctx.GlobalIsSet(EnsAPIFlag.Name) {
+ ensAPIs := ctx.GlobalStringSlice(EnsAPIFlag.Name)
+ // preserve backward compatibility to disable ENS with --ens-api=""
+ if len(ensAPIs) == 1 && ensAPIs[0] == "" {
+ ensAPIs = nil
+ }
+ for i := range ensAPIs {
+ ensAPIs[i] = expandPath(ensAPIs[i])
+ }
+
+ currentConfig.EnsAPIs = ensAPIs
+ }
+
+ if cors := ctx.GlobalString(CorsStringFlag.Name); cors != "" {
+ currentConfig.Cors = cors
+ }
+
+ if storePath := ctx.GlobalString(SwarmStorePath.Name); storePath != "" {
+ currentConfig.LocalStoreParams.ChunkDbPath = storePath
+ }
+
+ if storeCapacity := ctx.GlobalUint64(SwarmStoreCapacity.Name); storeCapacity != 0 {
+ currentConfig.LocalStoreParams.DbCapacity = storeCapacity
+ }
+
+ if ctx.GlobalIsSet(SwarmStoreCacheCapacity.Name) {
+ currentConfig.LocalStoreParams.CacheCapacity = ctx.GlobalUint(SwarmStoreCacheCapacity.Name)
+ }
+
+ if ctx.GlobalIsSet(SwarmBootnodeModeFlag.Name) {
+ currentConfig.BootnodeMode = ctx.GlobalBool(SwarmBootnodeModeFlag.Name)
+ }
+
+ if ctx.GlobalIsSet(SwarmGlobalStoreAPIFlag.Name) {
+ currentConfig.GlobalStoreAPI = ctx.GlobalString(SwarmGlobalStoreAPIFlag.Name)
+ }
+
+ return currentConfig
+
+}
+
+// envVarsOverride overrides the current config with whatver is provided in environment variables
+// most values are not allowed a zero value (empty string), if not otherwise noted
+func envVarsOverride(currentConfig *bzzapi.Config) (config *bzzapi.Config) {
+ if keyid := os.Getenv(SwarmEnvAccount); keyid != "" {
+ currentConfig.BzzAccount = keyid
+ }
+
+ if chbookaddr := os.Getenv(SwarmEnvChequebookAddr); chbookaddr != "" {
+ currentConfig.Contract = common.HexToAddress(chbookaddr)
+ }
+
+ if networkid := os.Getenv(SwarmEnvNetworkID); networkid != "" {
+ id, err := strconv.ParseUint(networkid, 10, 64)
+ if err != nil {
+ utils.Fatalf("invalid environment variable %s: %v", SwarmEnvNetworkID, err)
+ }
+ if id != 0 {
+ currentConfig.NetworkID = id
+ }
+ }
+
+ if datadir := os.Getenv(GethEnvDataDir); datadir != "" {
+ currentConfig.Path = expandPath(datadir)
+ }
+
+ bzzport := os.Getenv(SwarmEnvPort)
+ if len(bzzport) > 0 {
+ currentConfig.Port = bzzport
+ }
+
+ if bzzaddr := os.Getenv(SwarmEnvListenAddr); bzzaddr != "" {
+ currentConfig.ListenAddr = bzzaddr
+ }
+
+ if swapenable := os.Getenv(SwarmEnvSwapEnable); swapenable != "" {
+ swap, err := strconv.ParseBool(swapenable)
+ if err != nil {
+ utils.Fatalf("invalid environment variable %s: %v", SwarmEnvSwapEnable, err)
+ }
+ currentConfig.SwapEnabled = swap
+ }
+
+ if syncdisable := os.Getenv(SwarmEnvSyncDisable); syncdisable != "" {
+ sync, err := strconv.ParseBool(syncdisable)
+ if err != nil {
+ utils.Fatalf("invalid environment variable %s: %v", SwarmEnvSyncDisable, err)
+ }
+ currentConfig.SyncEnabled = !sync
+ }
+
+ if v := os.Getenv(SwarmEnvDeliverySkipCheck); v != "" {
+ skipCheck, err := strconv.ParseBool(v)
+ if err != nil {
+ currentConfig.DeliverySkipCheck = skipCheck
+ }
+ }
+
+ if v := os.Getenv(SwarmEnvSyncUpdateDelay); v != "" {
+ d, err := time.ParseDuration(v)
+ if err != nil {
+ utils.Fatalf("invalid environment variable %s: %v", SwarmEnvSyncUpdateDelay, err)
+ }
+ currentConfig.SyncUpdateDelay = d
+ }
+
+ if max := os.Getenv(SwarmEnvMaxStreamPeerServers); max != "" {
+ m, err := strconv.Atoi(max)
+ if err != nil {
+ utils.Fatalf("invalid environment variable %s: %v", SwarmEnvMaxStreamPeerServers, err)
+ }
+ currentConfig.MaxStreamPeerServers = m
+ }
+
+ if lne := os.Getenv(SwarmEnvLightNodeEnable); lne != "" {
+ lightnode, err := strconv.ParseBool(lne)
+ if err != nil {
+ utils.Fatalf("invalid environment variable %s: %v", SwarmEnvLightNodeEnable, err)
+ }
+ currentConfig.LightNodeEnabled = lightnode
+ }
+
+ if swapapi := os.Getenv(SwarmEnvSwapAPI); swapapi != "" {
+ currentConfig.SwapAPI = swapapi
+ }
+
+ if currentConfig.SwapEnabled && currentConfig.SwapAPI == "" {
+ utils.Fatalf(SwarmErrSwapSetNoAPI)
+ }
+
+ if ensapi := os.Getenv(SwarmEnvENSAPI); ensapi != "" {
+ currentConfig.EnsAPIs = strings.Split(ensapi, ",")
+ }
+
+ if ensaddr := os.Getenv(SwarmEnvENSAddr); ensaddr != "" {
+ currentConfig.EnsRoot = common.HexToAddress(ensaddr)
+ }
+
+ if cors := os.Getenv(SwarmEnvCORS); cors != "" {
+ currentConfig.Cors = cors
+ }
+
+ if bm := os.Getenv(SwarmEnvBootnodeMode); bm != "" {
+ bootnodeMode, err := strconv.ParseBool(bm)
+ if err != nil {
+ utils.Fatalf("invalid environment variable %s: %v", SwarmEnvBootnodeMode, err)
+ }
+ currentConfig.BootnodeMode = bootnodeMode
+ }
+
+ if api := os.Getenv(SwarmGlobalstoreAPI); api != "" {
+ currentConfig.GlobalStoreAPI = api
+ }
+
+ return currentConfig
+}
+
+// dumpConfig is the dumpconfig command.
+// writes a default config to STDOUT
+func dumpConfig(ctx *cli.Context) error {
+ cfg, err := buildConfig(ctx)
+ if err != nil {
+ utils.Fatalf(fmt.Sprintf("Uh oh - dumpconfig triggered an error %v", err))
+ }
+ comment := ""
+ out, err := tomlSettings.Marshal(&cfg)
+ if err != nil {
+ return err
+ }
+ io.WriteString(os.Stdout, comment)
+ os.Stdout.Write(out)
+ return nil
+}
+
+//validate configuration parameters
+func validateConfig(cfg *bzzapi.Config) (err error) {
+ for _, ensAPI := range cfg.EnsAPIs {
+ if ensAPI != "" {
+ if err := validateEnsAPIs(ensAPI); err != nil {
+ return fmt.Errorf("invalid format [tld:][contract-addr@]url for ENS API endpoint configuration %q: %v", ensAPI, err)
+ }
+ }
+ }
+ return nil
+}
+
+//validate EnsAPIs configuration parameter
+func validateEnsAPIs(s string) (err error) {
+ // missing contract address
+ if strings.HasPrefix(s, "@") {
+ return errors.New("missing contract address")
+ }
+ // missing url
+ if strings.HasSuffix(s, "@") {
+ return errors.New("missing url")
+ }
+ // missing tld
+ if strings.HasPrefix(s, ":") {
+ return errors.New("missing tld")
+ }
+ // missing url
+ if strings.HasSuffix(s, ":") {
+ return errors.New("missing url")
+ }
+ return nil
+}
+
+//print a Config as string
+func printConfig(config *bzzapi.Config) string {
+ out, err := tomlSettings.Marshal(&config)
+ if err != nil {
+ return fmt.Sprintf("Something is not right with the configuration: %v", err)
+ }
+ return string(out)
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/swarm/db.go b/vendor/github.com/ethereum/go-ethereum/cmd/swarm/db.go
new file mode 100644
index 00000000..7916beff
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/cmd/swarm/db.go
@@ -0,0 +1,147 @@
+// Copyright 2017 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// go-ethereum is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with go-ethereum. If not, see .
+
+package main
+
+import (
+ "fmt"
+ "io"
+ "os"
+ "path/filepath"
+
+ "github.com/ethereum/go-ethereum/cmd/utils"
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/log"
+ "github.com/ethereum/go-ethereum/swarm/storage"
+ "gopkg.in/urfave/cli.v1"
+)
+
+var dbCommand = cli.Command{
+ Name: "db",
+ CustomHelpTemplate: helpTemplate,
+ Usage: "manage the local chunk database",
+ ArgsUsage: "db COMMAND",
+ Description: "Manage the local chunk database",
+ Subcommands: []cli.Command{
+ {
+ Action: dbExport,
+ CustomHelpTemplate: helpTemplate,
+ Name: "export",
+ Usage: "export a local chunk database as a tar archive (use - to send to stdout)",
+ ArgsUsage: " ",
+ Description: `
+Export a local chunk database as a tar archive (use - to send to stdout).
+
+ swarm db export ~/.ethereum/swarm/bzz-KEY/chunks chunks.tar
+
+The export may be quite large, consider piping the output through the Unix
+pv(1) tool to get a progress bar:
+
+ swarm db export ~/.ethereum/swarm/bzz-KEY/chunks - | pv > chunks.tar
+`,
+ },
+ {
+ Action: dbImport,
+ CustomHelpTemplate: helpTemplate,
+ Name: "import",
+ Usage: "import chunks from a tar archive into a local chunk database (use - to read from stdin)",
+ ArgsUsage: " ",
+ Description: `Import chunks from a tar archive into a local chunk database (use - to read from stdin).
+
+ swarm db import ~/.ethereum/swarm/bzz-KEY/chunks chunks.tar
+
+The import may be quite large, consider piping the input through the Unix
+pv(1) tool to get a progress bar:
+
+ pv chunks.tar | swarm db import ~/.ethereum/swarm/bzz-KEY/chunks -`,
+ },
+ },
+}
+
+func dbExport(ctx *cli.Context) {
+ args := ctx.Args()
+ if len(args) != 3 {
+ utils.Fatalf("invalid arguments, please specify both (path to a local chunk database), (path to write the tar archive to, - for stdout) and the base key")
+ }
+
+ store, err := openLDBStore(args[0], common.Hex2Bytes(args[2]))
+ if err != nil {
+ utils.Fatalf("error opening local chunk database: %s", err)
+ }
+ defer store.Close()
+
+ var out io.Writer
+ if args[1] == "-" {
+ out = os.Stdout
+ } else {
+ f, err := os.Create(args[1])
+ if err != nil {
+ utils.Fatalf("error opening output file: %s", err)
+ }
+ defer f.Close()
+ out = f
+ }
+
+ count, err := store.Export(out)
+ if err != nil {
+ utils.Fatalf("error exporting local chunk database: %s", err)
+ }
+
+ log.Info(fmt.Sprintf("successfully exported %d chunks", count))
+}
+
+func dbImport(ctx *cli.Context) {
+ args := ctx.Args()
+ if len(args) != 3 {
+ utils.Fatalf("invalid arguments, please specify both (path to a local chunk database), (path to read the tar archive from, - for stdin) and the base key")
+ }
+
+ store, err := openLDBStore(args[0], common.Hex2Bytes(args[2]))
+ if err != nil {
+ utils.Fatalf("error opening local chunk database: %s", err)
+ }
+ defer store.Close()
+
+ var in io.Reader
+ if args[1] == "-" {
+ in = os.Stdin
+ } else {
+ f, err := os.Open(args[1])
+ if err != nil {
+ utils.Fatalf("error opening input file: %s", err)
+ }
+ defer f.Close()
+ in = f
+ }
+
+ count, err := store.Import(in)
+ if err != nil {
+ utils.Fatalf("error importing local chunk database: %s", err)
+ }
+
+ log.Info(fmt.Sprintf("successfully imported %d chunks", count))
+}
+
+func openLDBStore(path string, basekey []byte) (*storage.LDBStore, error) {
+ if _, err := os.Stat(filepath.Join(path, "CURRENT")); err != nil {
+ return nil, fmt.Errorf("invalid chunkdb path: %s", err)
+ }
+
+ storeparams := storage.NewDefaultStoreParams()
+ ldbparams := storage.NewLDBStoreParams(storeparams, path)
+ ldbparams.BaseKey = basekey
+ return storage.NewLDBStore(ldbparams)
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/swarm/download.go b/vendor/github.com/ethereum/go-ethereum/cmd/swarm/download.go
new file mode 100644
index 00000000..fcbefa02
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/cmd/swarm/download.go
@@ -0,0 +1,112 @@
+// Copyright 2018 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// go-ethereum is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with go-ethereum. If not, see .
+package main
+
+import (
+ "fmt"
+ "os"
+ "path/filepath"
+ "strings"
+
+ "github.com/ethereum/go-ethereum/cmd/utils"
+ "github.com/ethereum/go-ethereum/log"
+ "github.com/ethereum/go-ethereum/swarm/api"
+ swarm "github.com/ethereum/go-ethereum/swarm/api/client"
+ "gopkg.in/urfave/cli.v1"
+)
+
+var downloadCommand = cli.Command{
+ Action: download,
+ Name: "down",
+ Flags: []cli.Flag{SwarmRecursiveFlag, SwarmAccessPasswordFlag},
+ Usage: "downloads a swarm manifest or a file inside a manifest",
+ ArgsUsage: " []",
+ Description: `Downloads a swarm bzz uri to the given dir. When no dir is provided, working directory is assumed. --recursive flag is expected when downloading a manifest with multiple entries.`,
+}
+
+func download(ctx *cli.Context) {
+ log.Debug("downloading content using swarm down")
+ args := ctx.Args()
+ dest := "."
+
+ switch len(args) {
+ case 0:
+ utils.Fatalf("Usage: swarm down [options] []")
+ case 1:
+ log.Trace(fmt.Sprintf("swarm down: no destination path - assuming working dir"))
+ default:
+ log.Trace(fmt.Sprintf("destination path arg: %s", args[1]))
+ if absDest, err := filepath.Abs(args[1]); err == nil {
+ dest = absDest
+ } else {
+ utils.Fatalf("could not get download path: %v", err)
+ }
+ }
+
+ var (
+ bzzapi = strings.TrimRight(ctx.GlobalString(SwarmApiFlag.Name), "/")
+ isRecursive = ctx.Bool(SwarmRecursiveFlag.Name)
+ client = swarm.NewClient(bzzapi)
+ )
+
+ if fi, err := os.Stat(dest); err == nil {
+ if isRecursive && !fi.Mode().IsDir() {
+ utils.Fatalf("destination path is not a directory!")
+ }
+ } else {
+ if !os.IsNotExist(err) {
+ utils.Fatalf("could not stat path: %v", err)
+ }
+ }
+
+ uri, err := api.Parse(args[0])
+ if err != nil {
+ utils.Fatalf("could not parse uri argument: %v", err)
+ }
+
+ dl := func(credentials string) error {
+ // assume behaviour according to --recursive switch
+ if isRecursive {
+ if err := client.DownloadDirectory(uri.Addr, uri.Path, dest, credentials); err != nil {
+ if err == swarm.ErrUnauthorized {
+ return err
+ }
+ return fmt.Errorf("directory %s: %v", uri.Path, err)
+ }
+ } else {
+ // we are downloading a file
+ log.Debug("downloading file/path from a manifest", "uri.Addr", uri.Addr, "uri.Path", uri.Path)
+
+ err := client.DownloadFile(uri.Addr, uri.Path, dest, credentials)
+ if err != nil {
+ if err == swarm.ErrUnauthorized {
+ return err
+ }
+ return fmt.Errorf("file %s from address: %s: %v", uri.Path, uri.Addr, err)
+ }
+ }
+ return nil
+ }
+ if passwords := makePasswordList(ctx); passwords != nil {
+ password := getPassPhrase(fmt.Sprintf("Downloading %s is restricted", uri), 0, passwords)
+ err = dl(password)
+ } else {
+ err = dl("")
+ }
+ if err != nil {
+ utils.Fatalf("download: %v", err)
+ }
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/swarm/explore.go b/vendor/github.com/ethereum/go-ethereum/cmd/swarm/explore.go
new file mode 100644
index 00000000..5b5b8bf4
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/cmd/swarm/explore.go
@@ -0,0 +1,59 @@
+// Copyright 2019 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// go-ethereum is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with go-ethereum. If not, see .
+
+// Command bzzhash computes a swarm tree hash.
+package main
+
+import (
+ "context"
+ "fmt"
+ "os"
+
+ "github.com/ethereum/go-ethereum/cmd/utils"
+ "github.com/ethereum/go-ethereum/swarm/storage"
+ "gopkg.in/urfave/cli.v1"
+)
+
+var hashesCommand = cli.Command{
+ Action: hashes,
+ CustomHelpTemplate: helpTemplate,
+ Name: "hashes",
+ Usage: "print all hashes of a file to STDOUT",
+ ArgsUsage: "",
+ Description: "Prints all hashes of a file to STDOUT",
+}
+
+func hashes(ctx *cli.Context) {
+ args := ctx.Args()
+ if len(args) < 1 {
+ utils.Fatalf("Usage: swarm hashes ")
+ }
+ f, err := os.Open(args[0])
+ if err != nil {
+ utils.Fatalf("Error opening file " + args[1])
+ }
+ defer f.Close()
+
+ fileStore := storage.NewFileStore(&storage.FakeChunkStore{}, storage.NewFileStoreParams())
+ refs, err := fileStore.GetAllReferences(context.TODO(), f, false)
+ if err != nil {
+ utils.Fatalf("%v\n", err)
+ } else {
+ for _, r := range refs {
+ fmt.Println(r.String())
+ }
+ }
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/swarm/feeds.go b/vendor/github.com/ethereum/go-ethereum/cmd/swarm/feeds.go
new file mode 100644
index 00000000..6cd971a9
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/cmd/swarm/feeds.go
@@ -0,0 +1,238 @@
+// Copyright 2016 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// go-ethereum is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with go-ethereum. If not, see .
+
+// Command feed allows the user to create and update signed Swarm feeds
+package main
+
+import (
+ "fmt"
+ "strings"
+
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/common/hexutil"
+ "github.com/ethereum/go-ethereum/crypto"
+
+ "github.com/ethereum/go-ethereum/cmd/utils"
+ swarm "github.com/ethereum/go-ethereum/swarm/api/client"
+ "github.com/ethereum/go-ethereum/swarm/storage/feed"
+ "gopkg.in/urfave/cli.v1"
+)
+
+var feedCommand = cli.Command{
+ CustomHelpTemplate: helpTemplate,
+ Name: "feed",
+ Usage: "(Advanced) Create and update Swarm Feeds",
+ ArgsUsage: "",
+ Description: "Works with Swarm Feeds",
+ Subcommands: []cli.Command{
+ {
+ Action: feedCreateManifest,
+ CustomHelpTemplate: helpTemplate,
+ Name: "create",
+ Usage: "creates and publishes a new feed manifest",
+ Description: `creates and publishes a new feed manifest pointing to a specified user's updates about a particular topic.
+ The feed topic can be built in the following ways:
+ * use --topic to set the topic to an arbitrary binary hex string.
+ * use --name to set the topic to a human-readable name.
+ For example --name could be set to "profile-picture", meaning this feed allows to get this user's current profile picture.
+ * use both --topic and --name to create named subtopics.
+ For example, --topic could be set to an Ethereum contract address and --name could be set to "comments", meaning
+ this feed tracks a discussion about that contract.
+ The --user flag allows to have this manifest refer to a user other than yourself. If not specified,
+ it will then default to your local account (--bzzaccount)`,
+ Flags: []cli.Flag{SwarmFeedNameFlag, SwarmFeedTopicFlag, SwarmFeedUserFlag},
+ },
+ {
+ Action: feedUpdate,
+ CustomHelpTemplate: helpTemplate,
+ Name: "update",
+ Usage: "updates the content of an existing Swarm Feed",
+ ArgsUsage: "<0x Hex data>",
+ Description: `publishes a new update on the specified topic
+ The feed topic can be built in the following ways:
+ * use --topic to set the topic to an arbitrary binary hex string.
+ * use --name to set the topic to a human-readable name.
+ For example --name could be set to "profile-picture", meaning this feed allows to get this user's current profile picture.
+ * use both --topic and --name to create named subtopics.
+ For example, --topic could be set to an Ethereum contract address and --name could be set to "comments", meaning
+ this feed tracks a discussion about that contract.
+
+ If you have a manifest, you can specify it with --manifest to refer to the feed,
+ instead of using --topic / --name
+ `,
+ Flags: []cli.Flag{SwarmFeedManifestFlag, SwarmFeedNameFlag, SwarmFeedTopicFlag},
+ },
+ {
+ Action: feedInfo,
+ CustomHelpTemplate: helpTemplate,
+ Name: "info",
+ Usage: "obtains information about an existing Swarm feed",
+ Description: `obtains information about an existing Swarm feed
+ The topic can be specified directly with the --topic flag as an hex string
+ If no topic is specified, the default topic (zero) will be used
+ The --name flag can be used to specify subtopics with a specific name.
+ The --user flag allows to refer to a user other than yourself. If not specified,
+ it will then default to your local account (--bzzaccount)
+ If you have a manifest, you can specify it with --manifest instead of --topic / --name / ---user
+ to refer to the feed`,
+ Flags: []cli.Flag{SwarmFeedManifestFlag, SwarmFeedNameFlag, SwarmFeedTopicFlag, SwarmFeedUserFlag},
+ },
+ },
+}
+
+func NewGenericSigner(ctx *cli.Context) feed.Signer {
+ return feed.NewGenericSigner(getPrivKey(ctx))
+}
+
+func getTopic(ctx *cli.Context) (topic feed.Topic) {
+ var name = ctx.String(SwarmFeedNameFlag.Name)
+ var relatedTopic = ctx.String(SwarmFeedTopicFlag.Name)
+ var relatedTopicBytes []byte
+ var err error
+
+ if relatedTopic != "" {
+ relatedTopicBytes, err = hexutil.Decode(relatedTopic)
+ if err != nil {
+ utils.Fatalf("Error parsing topic: %s", err)
+ }
+ }
+
+ topic, err = feed.NewTopic(name, relatedTopicBytes)
+ if err != nil {
+ utils.Fatalf("Error parsing topic: %s", err)
+ }
+ return topic
+}
+
+// swarm feed create [--name ] [--data <0x Hexdata> [--multihash=false]]
+// swarm feed update <0x Hexdata> [--multihash=false]
+// swarm feed info
+
+func feedCreateManifest(ctx *cli.Context) {
+ var (
+ bzzapi = strings.TrimRight(ctx.GlobalString(SwarmApiFlag.Name), "/")
+ client = swarm.NewClient(bzzapi)
+ )
+
+ newFeedUpdateRequest := feed.NewFirstRequest(getTopic(ctx))
+ newFeedUpdateRequest.Feed.User = feedGetUser(ctx)
+
+ manifestAddress, err := client.CreateFeedWithManifest(newFeedUpdateRequest)
+ if err != nil {
+ utils.Fatalf("Error creating feed manifest: %s", err.Error())
+ return
+ }
+ fmt.Println(manifestAddress) // output manifest address to the user in a single line (useful for other commands to pick up)
+
+}
+
+func feedUpdate(ctx *cli.Context) {
+ args := ctx.Args()
+
+ var (
+ bzzapi = strings.TrimRight(ctx.GlobalString(SwarmApiFlag.Name), "/")
+ client = swarm.NewClient(bzzapi)
+ manifestAddressOrDomain = ctx.String(SwarmFeedManifestFlag.Name)
+ )
+
+ if len(args) < 1 {
+ fmt.Println("Incorrect number of arguments")
+ cli.ShowCommandHelpAndExit(ctx, "update", 1)
+ return
+ }
+
+ signer := NewGenericSigner(ctx)
+
+ data, err := hexutil.Decode(args[0])
+ if err != nil {
+ utils.Fatalf("Error parsing data: %s", err.Error())
+ return
+ }
+
+ var updateRequest *feed.Request
+ var query *feed.Query
+
+ if manifestAddressOrDomain == "" {
+ query = new(feed.Query)
+ query.User = signer.Address()
+ query.Topic = getTopic(ctx)
+ }
+
+ // Retrieve a feed update request
+ updateRequest, err = client.GetFeedRequest(query, manifestAddressOrDomain)
+ if err != nil {
+ utils.Fatalf("Error retrieving feed status: %s", err.Error())
+ }
+
+ // Check that the provided signer matches the request to sign
+ if updateRequest.User != signer.Address() {
+ utils.Fatalf("Signer address does not match the update request")
+ }
+
+ // set the new data
+ updateRequest.SetData(data)
+
+ // sign update
+ if err = updateRequest.Sign(signer); err != nil {
+ utils.Fatalf("Error signing feed update: %s", err.Error())
+ }
+
+ // post update
+ err = client.UpdateFeed(updateRequest)
+ if err != nil {
+ utils.Fatalf("Error updating feed: %s", err.Error())
+ return
+ }
+}
+
+func feedInfo(ctx *cli.Context) {
+ var (
+ bzzapi = strings.TrimRight(ctx.GlobalString(SwarmApiFlag.Name), "/")
+ client = swarm.NewClient(bzzapi)
+ manifestAddressOrDomain = ctx.String(SwarmFeedManifestFlag.Name)
+ )
+
+ var query *feed.Query
+ if manifestAddressOrDomain == "" {
+ query = new(feed.Query)
+ query.Topic = getTopic(ctx)
+ query.User = feedGetUser(ctx)
+ }
+
+ metadata, err := client.GetFeedRequest(query, manifestAddressOrDomain)
+ if err != nil {
+ utils.Fatalf("Error retrieving feed metadata: %s", err.Error())
+ return
+ }
+ encodedMetadata, err := metadata.MarshalJSON()
+ if err != nil {
+ utils.Fatalf("Error encoding metadata to JSON for display:%s", err)
+ }
+ fmt.Println(string(encodedMetadata))
+}
+
+func feedGetUser(ctx *cli.Context) common.Address {
+ var user = ctx.String(SwarmFeedUserFlag.Name)
+ if user != "" {
+ return common.HexToAddress(user)
+ }
+ pk := getPrivKey(ctx)
+ if pk == nil {
+ utils.Fatalf("Cannot read private key. Must specify --user or --bzzaccount")
+ }
+ return crypto.PubkeyToAddress(pk.PublicKey)
+
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/swarm/flags.go b/vendor/github.com/ethereum/go-ethereum/cmd/swarm/flags.go
new file mode 100644
index 00000000..5e1ada63
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/cmd/swarm/flags.go
@@ -0,0 +1,185 @@
+// Copyright 2018 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// go-ethereum is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with go-ethereum. If not, see .
+
+// Command feed allows the user to create and update signed Swarm feeds
+package main
+
+import cli "gopkg.in/urfave/cli.v1"
+
+var (
+ ChequebookAddrFlag = cli.StringFlag{
+ Name: "chequebook",
+ Usage: "chequebook contract address",
+ EnvVar: SwarmEnvChequebookAddr,
+ }
+ SwarmAccountFlag = cli.StringFlag{
+ Name: "bzzaccount",
+ Usage: "Swarm account key file",
+ EnvVar: SwarmEnvAccount,
+ }
+ SwarmListenAddrFlag = cli.StringFlag{
+ Name: "httpaddr",
+ Usage: "Swarm HTTP API listening interface",
+ EnvVar: SwarmEnvListenAddr,
+ }
+ SwarmPortFlag = cli.StringFlag{
+ Name: "bzzport",
+ Usage: "Swarm local http api port",
+ EnvVar: SwarmEnvPort,
+ }
+ SwarmNetworkIdFlag = cli.IntFlag{
+ Name: "bzznetworkid",
+ Usage: "Network identifier (integer, default 3=swarm testnet)",
+ EnvVar: SwarmEnvNetworkID,
+ }
+ SwarmSwapEnabledFlag = cli.BoolFlag{
+ Name: "swap",
+ Usage: "Swarm SWAP enabled (default false)",
+ EnvVar: SwarmEnvSwapEnable,
+ }
+ SwarmSwapAPIFlag = cli.StringFlag{
+ Name: "swap-api",
+ Usage: "URL of the Ethereum API provider to use to settle SWAP payments",
+ EnvVar: SwarmEnvSwapAPI,
+ }
+ SwarmSyncDisabledFlag = cli.BoolTFlag{
+ Name: "nosync",
+ Usage: "Disable swarm syncing",
+ EnvVar: SwarmEnvSyncDisable,
+ }
+ SwarmSyncUpdateDelay = cli.DurationFlag{
+ Name: "sync-update-delay",
+ Usage: "Duration for sync subscriptions update after no new peers are added (default 15s)",
+ EnvVar: SwarmEnvSyncUpdateDelay,
+ }
+ SwarmMaxStreamPeerServersFlag = cli.IntFlag{
+ Name: "max-stream-peer-servers",
+ Usage: "Limit of Stream peer servers, 0 denotes unlimited",
+ EnvVar: SwarmEnvMaxStreamPeerServers,
+ Value: 10000, // A very large default value is possible as stream servers have very small memory footprint
+ }
+ SwarmLightNodeEnabled = cli.BoolFlag{
+ Name: "lightnode",
+ Usage: "Enable Swarm LightNode (default false)",
+ EnvVar: SwarmEnvLightNodeEnable,
+ }
+ SwarmDeliverySkipCheckFlag = cli.BoolFlag{
+ Name: "delivery-skip-check",
+ Usage: "Skip chunk delivery check (default false)",
+ EnvVar: SwarmEnvDeliverySkipCheck,
+ }
+ EnsAPIFlag = cli.StringSliceFlag{
+ Name: "ens-api",
+ Usage: "ENS API endpoint for a TLD and with contract address, can be repeated, format [tld:][contract-addr@]url",
+ EnvVar: SwarmEnvENSAPI,
+ }
+ SwarmApiFlag = cli.StringFlag{
+ Name: "bzzapi",
+ Usage: "Specifies the Swarm HTTP endpoint to connect to",
+ Value: "http://127.0.0.1:8500",
+ }
+ SwarmRecursiveFlag = cli.BoolFlag{
+ Name: "recursive",
+ Usage: "Upload directories recursively",
+ }
+ SwarmWantManifestFlag = cli.BoolTFlag{
+ Name: "manifest",
+ Usage: "Automatic manifest upload (default true)",
+ }
+ SwarmUploadDefaultPath = cli.StringFlag{
+ Name: "defaultpath",
+ Usage: "path to file served for empty url path (none)",
+ }
+ SwarmAccessGrantKeyFlag = cli.StringFlag{
+ Name: "grant-key",
+ Usage: "grants a given public key access to an ACT",
+ }
+ SwarmAccessGrantKeysFlag = cli.StringFlag{
+ Name: "grant-keys",
+ Usage: "grants a given list of public keys in the following file (separated by line breaks) access to an ACT",
+ }
+ SwarmUpFromStdinFlag = cli.BoolFlag{
+ Name: "stdin",
+ Usage: "reads data to be uploaded from stdin",
+ }
+ SwarmUploadMimeType = cli.StringFlag{
+ Name: "mime",
+ Usage: "Manually specify MIME type",
+ }
+ SwarmEncryptedFlag = cli.BoolFlag{
+ Name: "encrypt",
+ Usage: "use encrypted upload",
+ }
+ SwarmAccessPasswordFlag = cli.StringFlag{
+ Name: "password",
+ Usage: "Password",
+ EnvVar: SwarmAccessPassword,
+ }
+ SwarmDryRunFlag = cli.BoolFlag{
+ Name: "dry-run",
+ Usage: "dry-run",
+ }
+ CorsStringFlag = cli.StringFlag{
+ Name: "corsdomain",
+ Usage: "Domain on which to send Access-Control-Allow-Origin header (multiple domains can be supplied separated by a ',')",
+ EnvVar: SwarmEnvCORS,
+ }
+ SwarmStorePath = cli.StringFlag{
+ Name: "store.path",
+ Usage: "Path to leveldb chunk DB (default <$GETH_ENV_DIR>/swarm/bzz-<$BZZ_KEY>/chunks)",
+ EnvVar: SwarmEnvStorePath,
+ }
+ SwarmStoreCapacity = cli.Uint64Flag{
+ Name: "store.size",
+ Usage: "Number of chunks (5M is roughly 20-25GB) (default 5000000)",
+ EnvVar: SwarmEnvStoreCapacity,
+ }
+ SwarmStoreCacheCapacity = cli.UintFlag{
+ Name: "store.cache.size",
+ Usage: "Number of recent chunks cached in memory",
+ EnvVar: SwarmEnvStoreCacheCapacity,
+ Value: 10000,
+ }
+ SwarmCompressedFlag = cli.BoolFlag{
+ Name: "compressed",
+ Usage: "Prints encryption keys in compressed form",
+ }
+ SwarmBootnodeModeFlag = cli.BoolFlag{
+ Name: "bootnode-mode",
+ Usage: "Run Swarm in Bootnode mode",
+ }
+ SwarmFeedNameFlag = cli.StringFlag{
+ Name: "name",
+ Usage: "User-defined name for the new feed, limited to 32 characters. If combined with topic, it will refer to a subtopic with this name",
+ }
+ SwarmFeedTopicFlag = cli.StringFlag{
+ Name: "topic",
+ Usage: "User-defined topic this feed is tracking, hex encoded. Limited to 64 hexadecimal characters",
+ }
+ SwarmFeedManifestFlag = cli.StringFlag{
+ Name: "manifest",
+ Usage: "Refers to the feed through a manifest",
+ }
+ SwarmFeedUserFlag = cli.StringFlag{
+ Name: "user",
+ Usage: "Indicates the user who updates the feed",
+ }
+ SwarmGlobalStoreAPIFlag = cli.StringFlag{
+ Name: "globalstore-api",
+ Usage: "URL of the Global Store API provider (only for testing)",
+ EnvVar: SwarmGlobalstoreAPI,
+ }
+)
diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/swarm/fs.go b/vendor/github.com/ethereum/go-ethereum/cmd/swarm/fs.go
new file mode 100644
index 00000000..7f156523
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/cmd/swarm/fs.go
@@ -0,0 +1,162 @@
+// Copyright 2018 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// go-ethereum is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with go-ethereum. If not, see .
+
+package main
+
+import (
+ "context"
+ "fmt"
+ "path/filepath"
+ "strings"
+ "time"
+
+ "github.com/ethereum/go-ethereum/cmd/utils"
+ "github.com/ethereum/go-ethereum/log"
+ "github.com/ethereum/go-ethereum/rpc"
+ "github.com/ethereum/go-ethereum/swarm/fuse"
+ "gopkg.in/urfave/cli.v1"
+)
+
+var fsCommand = cli.Command{
+ Name: "fs",
+ CustomHelpTemplate: helpTemplate,
+ Usage: "perform FUSE operations",
+ ArgsUsage: "fs COMMAND",
+ Description: "Performs FUSE operations by mounting/unmounting/listing mount points. This assumes you already have a Swarm node running locally. For all operation you must reference the correct path to bzzd.ipc in order to communicate with the node",
+ Subcommands: []cli.Command{
+ {
+ Action: mount,
+ CustomHelpTemplate: helpTemplate,
+ Name: "mount",
+ Usage: "mount a swarm hash to a mount point",
+ ArgsUsage: "swarm fs mount ",
+ Description: "Mounts a Swarm manifest hash to a given mount point. This assumes you already have a Swarm node running locally. You must reference the correct path to your bzzd.ipc file",
+ },
+ {
+ Action: unmount,
+ CustomHelpTemplate: helpTemplate,
+ Name: "unmount",
+ Usage: "unmount a swarmfs mount",
+ ArgsUsage: "swarm fs unmount ",
+ Description: "Unmounts a swarmfs mount residing at . This assumes you already have a Swarm node running locally. You must reference the correct path to your bzzd.ipc file",
+ },
+ {
+ Action: listMounts,
+ CustomHelpTemplate: helpTemplate,
+ Name: "list",
+ Usage: "list swarmfs mounts",
+ ArgsUsage: "swarm fs list",
+ Description: "Lists all mounted swarmfs volumes. This assumes you already have a Swarm node running locally. You must reference the correct path to your bzzd.ipc file",
+ },
+ },
+}
+
+func mount(cliContext *cli.Context) {
+ args := cliContext.Args()
+ if len(args) < 2 {
+ utils.Fatalf("Usage: swarm fs mount ")
+ }
+
+ client, err := dialRPC(cliContext)
+ if err != nil {
+ utils.Fatalf("had an error dailing to RPC endpoint: %v", err)
+ }
+ defer client.Close()
+
+ ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
+ defer cancel()
+
+ mf := &fuse.MountInfo{}
+ mountPoint, err := filepath.Abs(filepath.Clean(args[1]))
+ if err != nil {
+ utils.Fatalf("error expanding path for mount point: %v", err)
+ }
+ err = client.CallContext(ctx, mf, "swarmfs_mount", args[0], mountPoint)
+ if err != nil {
+ utils.Fatalf("had an error calling the RPC endpoint while mounting: %v", err)
+ }
+}
+
+func unmount(cliContext *cli.Context) {
+ args := cliContext.Args()
+
+ if len(args) < 1 {
+ utils.Fatalf("Usage: swarm fs unmount ")
+ }
+ client, err := dialRPC(cliContext)
+ if err != nil {
+ utils.Fatalf("had an error dailing to RPC endpoint: %v", err)
+ }
+ defer client.Close()
+
+ ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
+ defer cancel()
+
+ mf := fuse.MountInfo{}
+ err = client.CallContext(ctx, &mf, "swarmfs_unmount", args[0])
+ if err != nil {
+ utils.Fatalf("encountered an error calling the RPC endpoint while unmounting: %v", err)
+ }
+ fmt.Printf("%s\n", mf.LatestManifest) //print the latest manifest hash for user reference
+}
+
+func listMounts(cliContext *cli.Context) {
+ client, err := dialRPC(cliContext)
+ if err != nil {
+ utils.Fatalf("had an error dailing to RPC endpoint: %v", err)
+ }
+ defer client.Close()
+
+ ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
+ defer cancel()
+
+ var mf []fuse.MountInfo
+ err = client.CallContext(ctx, &mf, "swarmfs_listmounts")
+ if err != nil {
+ utils.Fatalf("encountered an error calling the RPC endpoint while listing mounts: %v", err)
+ }
+ if len(mf) == 0 {
+ fmt.Print("Could not found any swarmfs mounts. Please make sure you've specified the correct RPC endpoint\n")
+ } else {
+ fmt.Printf("Found %d swarmfs mount(s):\n", len(mf))
+ for i, mountInfo := range mf {
+ fmt.Printf("%d:\n", i)
+ fmt.Printf("\tMount point: %s\n", mountInfo.MountPoint)
+ fmt.Printf("\tLatest Manifest: %s\n", mountInfo.LatestManifest)
+ fmt.Printf("\tStart Manifest: %s\n", mountInfo.StartManifest)
+ }
+ }
+}
+
+func dialRPC(ctx *cli.Context) (*rpc.Client, error) {
+ endpoint := getIPCEndpoint(ctx)
+ log.Info("IPC endpoint", "path", endpoint)
+ return rpc.Dial(endpoint)
+}
+
+func getIPCEndpoint(ctx *cli.Context) string {
+ cfg := defaultNodeConfig
+ utils.SetNodeConfig(ctx, &cfg)
+
+ endpoint := cfg.IPCEndpoint()
+
+ if strings.HasPrefix(endpoint, "rpc:") || strings.HasPrefix(endpoint, "ipc:") {
+ // Backwards compatibility with geth < 1.5 which required
+ // these prefixes.
+ endpoint = endpoint[4:]
+ }
+ return endpoint
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/swarm/global-store/explorer.go b/vendor/github.com/ethereum/go-ethereum/cmd/swarm/global-store/explorer.go
new file mode 100644
index 00000000..634ff1eb
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/cmd/swarm/global-store/explorer.go
@@ -0,0 +1,66 @@
+// Copyright 2019 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// go-ethereum is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with go-ethereum. If not, see .
+
+package main
+
+import (
+ "context"
+ "fmt"
+ "net"
+ "net/http"
+ "time"
+
+ "github.com/ethereum/go-ethereum/log"
+ "github.com/ethereum/go-ethereum/swarm/storage/mock"
+ "github.com/ethereum/go-ethereum/swarm/storage/mock/explorer"
+ cli "gopkg.in/urfave/cli.v1"
+)
+
+// serveChunkExplorer starts an http server in background with chunk explorer handler
+// using the provided global store. Server is started if the returned shutdown function
+// is not nil.
+func serveChunkExplorer(ctx *cli.Context, globalStore mock.GlobalStorer) (shutdown func(), err error) {
+ if !ctx.IsSet("explorer-address") {
+ return nil, nil
+ }
+
+ corsOrigins := ctx.StringSlice("explorer-cors-origin")
+ server := &http.Server{
+ Handler: explorer.NewHandler(globalStore, corsOrigins),
+ IdleTimeout: 30 * time.Minute,
+ ReadTimeout: 2 * time.Minute,
+ WriteTimeout: 2 * time.Minute,
+ }
+ listener, err := net.Listen("tcp", ctx.String("explorer-address"))
+ if err != nil {
+ return nil, fmt.Errorf("explorer: %v", err)
+ }
+ log.Info("chunk explorer http", "address", listener.Addr().String(), "origins", corsOrigins)
+
+ go func() {
+ if err := server.Serve(listener); err != nil {
+ log.Error("chunk explorer", "err", err)
+ }
+ }()
+
+ return func() {
+ ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+ defer cancel()
+ if err := server.Shutdown(ctx); err != nil {
+ log.Error("chunk explorer: shutdown", "err", err)
+ }
+ }, nil
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/swarm/global-store/global_store.go b/vendor/github.com/ethereum/go-ethereum/cmd/swarm/global-store/global_store.go
new file mode 100644
index 00000000..f93b464d
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/cmd/swarm/global-store/global_store.go
@@ -0,0 +1,120 @@
+// Copyright 2019 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// go-ethereum is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with go-ethereum. If not, see .
+
+package main
+
+import (
+ "io"
+ "net"
+ "net/http"
+ "os"
+
+ "github.com/ethereum/go-ethereum/log"
+ "github.com/ethereum/go-ethereum/rpc"
+ "github.com/ethereum/go-ethereum/swarm/storage/mock"
+ "github.com/ethereum/go-ethereum/swarm/storage/mock/db"
+ "github.com/ethereum/go-ethereum/swarm/storage/mock/mem"
+ cli "gopkg.in/urfave/cli.v1"
+)
+
+// startHTTP starts a global store with HTTP RPC server.
+// It is used for "http" cli command.
+func startHTTP(ctx *cli.Context) (err error) {
+ server, cleanup, err := newServer(ctx)
+ if err != nil {
+ return err
+ }
+ defer cleanup()
+
+ listener, err := net.Listen("tcp", ctx.String("addr"))
+ if err != nil {
+ return err
+ }
+ log.Info("http", "address", listener.Addr().String())
+
+ return http.Serve(listener, server)
+}
+
+// startWS starts a global store with WebSocket RPC server.
+// It is used for "websocket" cli command.
+func startWS(ctx *cli.Context) (err error) {
+ server, cleanup, err := newServer(ctx)
+ if err != nil {
+ return err
+ }
+ defer cleanup()
+
+ listener, err := net.Listen("tcp", ctx.String("addr"))
+ if err != nil {
+ return err
+ }
+ origins := ctx.StringSlice("origins")
+ log.Info("websocket", "address", listener.Addr().String(), "origins", origins)
+
+ return http.Serve(listener, server.WebsocketHandler(origins))
+}
+
+// newServer creates a global store and starts a chunk explorer server if configured.
+// Returned cleanup function should be called only if err is nil.
+func newServer(ctx *cli.Context) (server *rpc.Server, cleanup func(), err error) {
+ log.PrintOrigins(true)
+ log.Root().SetHandler(log.LvlFilterHandler(log.Lvl(ctx.Int("verbosity")), log.StreamHandler(os.Stdout, log.TerminalFormat(false))))
+
+ cleanup = func() {}
+ var globalStore mock.GlobalStorer
+ dir := ctx.String("dir")
+ if dir != "" {
+ dbStore, err := db.NewGlobalStore(dir)
+ if err != nil {
+ return nil, nil, err
+ }
+ cleanup = func() {
+ if err := dbStore.Close(); err != nil {
+ log.Error("global store: close", "err", err)
+ }
+ }
+ globalStore = dbStore
+ log.Info("database global store", "dir", dir)
+ } else {
+ globalStore = mem.NewGlobalStore()
+ log.Info("in-memory global store")
+ }
+
+ server = rpc.NewServer()
+ if err := server.RegisterName("mockStore", globalStore); err != nil {
+ cleanup()
+ return nil, nil, err
+ }
+
+ shutdown, err := serveChunkExplorer(ctx, globalStore)
+ if err != nil {
+ cleanup()
+ return nil, nil, err
+ }
+ if shutdown != nil {
+ cleanup = func() {
+ shutdown()
+
+ if c, ok := globalStore.(io.Closer); ok {
+ if err := c.Close(); err != nil {
+ log.Error("global store: close", "err", err)
+ }
+ }
+ }
+ }
+
+ return server, cleanup, nil
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/swarm/global-store/main.go b/vendor/github.com/ethereum/go-ethereum/cmd/swarm/global-store/main.go
new file mode 100644
index 00000000..52fafc8f
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/cmd/swarm/global-store/main.go
@@ -0,0 +1,120 @@
+// Copyright 2019 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// go-ethereum is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with go-ethereum. If not, see .
+
+package main
+
+import (
+ "os"
+
+ "github.com/ethereum/go-ethereum/log"
+ cli "gopkg.in/urfave/cli.v1"
+)
+
+var (
+ version = "0.1"
+ gitCommit string // Git SHA1 commit hash of the release (set via linker flags)
+)
+
+func main() {
+ err := newApp().Run(os.Args)
+ if err != nil {
+ log.Error(err.Error())
+ os.Exit(1)
+ }
+}
+
+// newApp construct a new instance of Swarm Global Store.
+// Method Run is called on it in the main function and in tests.
+func newApp() (app *cli.App) {
+ app = cli.NewApp()
+ app.Name = "global-store"
+ app.Version = version
+ if len(gitCommit) >= 8 {
+ app.Version += "-" + gitCommit[:8]
+ }
+ app.Usage = "Swarm Global Store"
+
+ // app flags (for all commands)
+ app.Flags = []cli.Flag{
+ cli.IntFlag{
+ Name: "verbosity",
+ Value: 3,
+ Usage: "Verbosity level.",
+ },
+ cli.StringFlag{
+ Name: "explorer-address",
+ Value: "",
+ Usage: "Chunk explorer HTTP listener address.",
+ },
+ cli.StringSliceFlag{
+ Name: "explorer-cors-origin",
+ Value: nil,
+ Usage: "Chunk explorer CORS origin (can be specified multiple times).",
+ },
+ }
+
+ app.Commands = []cli.Command{
+ {
+ Name: "http",
+ Aliases: []string{"h"},
+ Usage: "Start swarm global store with HTTP server.",
+ Action: startHTTP,
+ // Flags only for "start" command.
+ // Allow app flags to be specified after the
+ // command argument.
+ Flags: append(app.Flags,
+ cli.StringFlag{
+ Name: "dir",
+ Value: "",
+ Usage: "Data directory.",
+ },
+ cli.StringFlag{
+ Name: "addr",
+ Value: "0.0.0.0:3033",
+ Usage: "Address to listen for HTTP connections.",
+ },
+ ),
+ },
+ {
+ Name: "websocket",
+ Aliases: []string{"ws"},
+ Usage: "Start swarm global store with WebSocket server.",
+ Action: startWS,
+ // Flags only for "start" command.
+ // Allow app flags to be specified after the
+ // command argument.
+ Flags: append(app.Flags,
+ cli.StringFlag{
+ Name: "dir",
+ Value: "",
+ Usage: "Data directory.",
+ },
+ cli.StringFlag{
+ Name: "addr",
+ Value: "0.0.0.0:3033",
+ Usage: "Address to listen for WebSocket connections.",
+ },
+ cli.StringSliceFlag{
+ Name: "origin",
+ Value: nil,
+ Usage: "WebSocket CORS origin (can be specified multiple times).",
+ },
+ ),
+ },
+ }
+
+ return app
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/swarm/hash.go b/vendor/github.com/ethereum/go-ethereum/cmd/swarm/hash.go
new file mode 100644
index 00000000..2df02c0e
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/cmd/swarm/hash.go
@@ -0,0 +1,115 @@
+// Copyright 2016 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// go-ethereum is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with go-ethereum. If not, see .
+
+// Command bzzhash computes a swarm tree hash.
+package main
+
+import (
+ "context"
+ "encoding/hex"
+ "fmt"
+ "os"
+
+ "github.com/ethereum/go-ethereum/cmd/utils"
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/contracts/ens"
+ "github.com/ethereum/go-ethereum/swarm/storage"
+ "gopkg.in/urfave/cli.v1"
+)
+
+var hashCommand = cli.Command{
+ Action: hash,
+ CustomHelpTemplate: helpTemplate,
+ Name: "hash",
+ Usage: "print the swarm hash of a file or directory",
+ ArgsUsage: "",
+ Description: "Prints the swarm hash of file or directory",
+ Subcommands: []cli.Command{
+ {
+ CustomHelpTemplate: helpTemplate,
+ Name: "ens",
+ Usage: "converts a swarm hash to an ens EIP1577 compatible CIDv1 hash",
+ ArgsUsage: "][",
+ Description: "",
+ Subcommands: []cli.Command{
+ {
+ Action: encodeEipHash,
+ CustomHelpTemplate: helpTemplate,
+ Name: "contenthash",
+ Usage: "converts a swarm hash to an ens EIP1577 compatible CIDv1 hash",
+ ArgsUsage: "][",
+ Description: "",
+ },
+ {
+ Action: ensNodeHash,
+ CustomHelpTemplate: helpTemplate,
+ Name: "node",
+ Usage: "converts an ens name to an ENS node hash",
+ ArgsUsage: "][",
+ Description: "",
+ },
+ },
+ },
+ }}
+
+func hash(ctx *cli.Context) {
+ args := ctx.Args()
+ if len(args) < 1 {
+ utils.Fatalf("Usage: swarm hash ")
+ }
+ f, err := os.Open(args[0])
+ if err != nil {
+ utils.Fatalf("Error opening file " + args[1])
+ }
+ defer f.Close()
+
+ stat, _ := f.Stat()
+ fileStore := storage.NewFileStore(&storage.FakeChunkStore{}, storage.NewFileStoreParams())
+ addr, _, err := fileStore.Store(context.TODO(), f, stat.Size(), false)
+ if err != nil {
+ utils.Fatalf("%v\n", err)
+ } else {
+ fmt.Printf("%v\n", addr)
+ }
+}
+func ensNodeHash(ctx *cli.Context) {
+ args := ctx.Args()
+ if len(args) < 1 {
+ utils.Fatalf("Usage: swarm hash ens node ")
+ }
+ ensName := args[0]
+
+ hash := ens.EnsNode(ensName)
+
+ stringHex := hex.EncodeToString(hash[:])
+ fmt.Println(stringHex)
+}
+func encodeEipHash(ctx *cli.Context) {
+ args := ctx.Args()
+ if len(args) < 1 {
+ utils.Fatalf("Usage: swarm hash ens ")
+ }
+ swarmHash := args[0]
+
+ hash := common.HexToHash(swarmHash)
+ ensHash, err := ens.EncodeSwarmHash(hash)
+ if err != nil {
+ utils.Fatalf("error converting swarm hash", err)
+ }
+
+ stringHex := hex.EncodeToString(ensHash)
+ fmt.Println(stringHex)
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/swarm/list.go b/vendor/github.com/ethereum/go-ethereum/cmd/swarm/list.go
new file mode 100644
index 00000000..5d35154a
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/cmd/swarm/list.go
@@ -0,0 +1,70 @@
+// Copyright 2017 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// go-ethereum is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with go-ethereum. If not, see .
+
+package main
+
+import (
+ "fmt"
+ "os"
+ "strings"
+ "text/tabwriter"
+
+ "github.com/ethereum/go-ethereum/cmd/utils"
+ swarm "github.com/ethereum/go-ethereum/swarm/api/client"
+ "gopkg.in/urfave/cli.v1"
+)
+
+var listCommand = cli.Command{
+ Action: list,
+ CustomHelpTemplate: helpTemplate,
+ Name: "ls",
+ Usage: "list files and directories contained in a manifest",
+ ArgsUsage: " []",
+ Description: "Lists files and directories contained in a manifest",
+}
+
+func list(ctx *cli.Context) {
+ args := ctx.Args()
+
+ if len(args) < 1 {
+ utils.Fatalf("Please supply a manifest reference as the first argument")
+ } else if len(args) > 2 {
+ utils.Fatalf("Too many arguments - usage 'swarm ls manifest [prefix]'")
+ }
+ manifest := args[0]
+
+ var prefix string
+ if len(args) == 2 {
+ prefix = args[1]
+ }
+
+ bzzapi := strings.TrimRight(ctx.GlobalString(SwarmApiFlag.Name), "/")
+ client := swarm.NewClient(bzzapi)
+ list, err := client.List(manifest, prefix, "")
+ if err != nil {
+ utils.Fatalf("Failed to generate file and directory list: %s", err)
+ }
+
+ w := tabwriter.NewWriter(os.Stdout, 1, 2, 2, ' ', 0)
+ defer w.Flush()
+ fmt.Fprintln(w, "HASH\tCONTENT TYPE\tPATH")
+ for _, prefix := range list.CommonPrefixes {
+ fmt.Fprintf(w, "%s\t%s\t%s\n", "", "DIR", prefix)
+ }
+ for _, entry := range list.Entries {
+ fmt.Fprintf(w, "%s\t%s\t%s\n", entry.Hash, entry.ContentType, entry.Path)
+ }
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/swarm/main.go b/vendor/github.com/ethereum/go-ethereum/cmd/swarm/main.go
new file mode 100644
index 00000000..a4041eb3
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/cmd/swarm/main.go
@@ -0,0 +1,475 @@
+// Copyright 2016 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// go-ethereum is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with go-ethereum. If not, see .
+
+package main
+
+import (
+ "crypto/ecdsa"
+ "encoding/hex"
+ "fmt"
+ "io/ioutil"
+ "os"
+ "os/signal"
+ "runtime"
+ "sort"
+ "strconv"
+ "strings"
+ "syscall"
+
+ "github.com/ethereum/go-ethereum/accounts"
+ "github.com/ethereum/go-ethereum/accounts/keystore"
+ "github.com/ethereum/go-ethereum/cmd/utils"
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/console"
+ "github.com/ethereum/go-ethereum/crypto"
+ "github.com/ethereum/go-ethereum/internal/debug"
+ "github.com/ethereum/go-ethereum/log"
+ "github.com/ethereum/go-ethereum/node"
+ "github.com/ethereum/go-ethereum/p2p/enode"
+ "github.com/ethereum/go-ethereum/rpc"
+ "github.com/ethereum/go-ethereum/swarm"
+ bzzapi "github.com/ethereum/go-ethereum/swarm/api"
+ swarmmetrics "github.com/ethereum/go-ethereum/swarm/metrics"
+ "github.com/ethereum/go-ethereum/swarm/storage/mock"
+ mockrpc "github.com/ethereum/go-ethereum/swarm/storage/mock/rpc"
+ "github.com/ethereum/go-ethereum/swarm/tracing"
+ sv "github.com/ethereum/go-ethereum/swarm/version"
+
+ cli "gopkg.in/urfave/cli.v1"
+)
+
+const clientIdentifier = "swarm"
+const helpTemplate = `NAME:
+{{.HelpName}} - {{.Usage}}
+
+USAGE:
+{{if .UsageText}}{{.UsageText}}{{else}}{{.HelpName}}{{if .VisibleFlags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Category}}
+
+CATEGORY:
+{{.Category}}{{end}}{{if .Description}}
+
+DESCRIPTION:
+{{.Description}}{{end}}{{if .VisibleFlags}}
+
+OPTIONS:
+{{range .VisibleFlags}}{{.}}
+{{end}}{{end}}
+`
+
+// Git SHA1 commit hash of the release (set via linker flags)
+// this variable will be assigned if corresponding parameter is passed with install, but not with test
+// e.g.: go install -ldflags "-X main.gitCommit=ed1312d01b19e04ef578946226e5d8069d5dfd5a" ./cmd/swarm
+var gitCommit string
+
+//declare a few constant error messages, useful for later error check comparisons in test
+var (
+ SwarmErrNoBZZAccount = "bzzaccount option is required but not set; check your config file, command line or environment variables"
+ SwarmErrSwapSetNoAPI = "SWAP is enabled but --swap-api is not set"
+)
+
+// this help command gets added to any subcommand that does not define it explicitly
+var defaultSubcommandHelp = cli.Command{
+ Action: func(ctx *cli.Context) { cli.ShowCommandHelpAndExit(ctx, "", 1) },
+ CustomHelpTemplate: helpTemplate,
+ Name: "help",
+ Usage: "shows this help",
+ Hidden: true,
+}
+
+var defaultNodeConfig = node.DefaultConfig
+
+// This init function sets defaults so cmd/swarm can run alongside geth.
+func init() {
+ sv.GitCommit = gitCommit
+ defaultNodeConfig.Name = clientIdentifier
+ defaultNodeConfig.Version = sv.VersionWithCommit(gitCommit)
+ defaultNodeConfig.P2P.ListenAddr = ":30399"
+ defaultNodeConfig.IPCPath = "bzzd.ipc"
+ // Set flag defaults for --help display.
+ utils.ListenPortFlag.Value = 30399
+}
+
+var app = utils.NewApp("", "Ethereum Swarm")
+
+// This init function creates the cli.App.
+func init() {
+ app.Action = bzzd
+ app.Version = sv.ArchiveVersion(gitCommit)
+ app.Copyright = "Copyright 2013-2016 The go-ethereum Authors"
+ app.Commands = []cli.Command{
+ {
+ Action: version,
+ CustomHelpTemplate: helpTemplate,
+ Name: "version",
+ Usage: "Print version numbers",
+ Description: "The output of this command is supposed to be machine-readable",
+ },
+ {
+ Action: keys,
+ CustomHelpTemplate: helpTemplate,
+ Name: "print-keys",
+ Flags: []cli.Flag{SwarmCompressedFlag},
+ Usage: "Print public key information",
+ Description: "The output of this command is supposed to be machine-readable",
+ },
+ // See upload.go
+ upCommand,
+ // See access.go
+ accessCommand,
+ // See feeds.go
+ feedCommand,
+ // See list.go
+ listCommand,
+ // See hash.go
+ hashCommand,
+ // See download.go
+ downloadCommand,
+ // See manifest.go
+ manifestCommand,
+ // See fs.go
+ fsCommand,
+ // See db.go
+ dbCommand,
+ // See config.go
+ DumpConfigCommand,
+ // hashesCommand
+ hashesCommand,
+ }
+
+ // append a hidden help subcommand to all commands that have subcommands
+ // if a help command was already defined above, that one will take precedence.
+ addDefaultHelpSubcommands(app.Commands)
+
+ sort.Sort(cli.CommandsByName(app.Commands))
+
+ app.Flags = []cli.Flag{
+ utils.IdentityFlag,
+ utils.DataDirFlag,
+ utils.BootnodesFlag,
+ utils.KeyStoreDirFlag,
+ utils.ListenPortFlag,
+ utils.DiscoveryV5Flag,
+ utils.NetrestrictFlag,
+ utils.NodeKeyFileFlag,
+ utils.NodeKeyHexFlag,
+ utils.MaxPeersFlag,
+ utils.NATFlag,
+ utils.IPCDisabledFlag,
+ utils.IPCPathFlag,
+ utils.PasswordFileFlag,
+ // bzzd-specific flags
+ CorsStringFlag,
+ EnsAPIFlag,
+ SwarmTomlConfigPathFlag,
+ SwarmSwapEnabledFlag,
+ SwarmSwapAPIFlag,
+ SwarmSyncDisabledFlag,
+ SwarmSyncUpdateDelay,
+ SwarmMaxStreamPeerServersFlag,
+ SwarmLightNodeEnabled,
+ SwarmDeliverySkipCheckFlag,
+ SwarmListenAddrFlag,
+ SwarmPortFlag,
+ SwarmAccountFlag,
+ SwarmNetworkIdFlag,
+ ChequebookAddrFlag,
+ // upload flags
+ SwarmApiFlag,
+ SwarmRecursiveFlag,
+ SwarmWantManifestFlag,
+ SwarmUploadDefaultPath,
+ SwarmUpFromStdinFlag,
+ SwarmUploadMimeType,
+ // bootnode mode
+ SwarmBootnodeModeFlag,
+ // storage flags
+ SwarmStorePath,
+ SwarmStoreCapacity,
+ SwarmStoreCacheCapacity,
+ SwarmGlobalStoreAPIFlag,
+ }
+ rpcFlags := []cli.Flag{
+ utils.WSEnabledFlag,
+ utils.WSListenAddrFlag,
+ utils.WSPortFlag,
+ utils.WSApiFlag,
+ utils.WSAllowedOriginsFlag,
+ }
+ app.Flags = append(app.Flags, rpcFlags...)
+ app.Flags = append(app.Flags, debug.Flags...)
+ app.Flags = append(app.Flags, swarmmetrics.Flags...)
+ app.Flags = append(app.Flags, tracing.Flags...)
+ app.Before = func(ctx *cli.Context) error {
+ runtime.GOMAXPROCS(runtime.NumCPU())
+ if err := debug.Setup(ctx, ""); err != nil {
+ return err
+ }
+ swarmmetrics.Setup(ctx)
+ tracing.Setup(ctx)
+ return nil
+ }
+ app.After = func(ctx *cli.Context) error {
+ debug.Exit()
+ return nil
+ }
+}
+
+func main() {
+ if err := app.Run(os.Args); err != nil {
+ fmt.Fprintln(os.Stderr, err)
+ os.Exit(1)
+ }
+}
+
+func keys(ctx *cli.Context) error {
+ privateKey := getPrivKey(ctx)
+ pubkey := crypto.FromECDSAPub(&privateKey.PublicKey)
+ pubkeyhex := hex.EncodeToString(pubkey)
+ pubCompressed := hex.EncodeToString(crypto.CompressPubkey(&privateKey.PublicKey))
+ bzzkey := crypto.Keccak256Hash(pubkey).Hex()
+
+ if !ctx.Bool(SwarmCompressedFlag.Name) {
+ fmt.Println(fmt.Sprintf("bzzkey=%s", bzzkey[2:]))
+ fmt.Println(fmt.Sprintf("publicKey=%s", pubkeyhex))
+ }
+ fmt.Println(fmt.Sprintf("publicKeyCompressed=%s", pubCompressed))
+
+ return nil
+}
+
+func version(ctx *cli.Context) error {
+ fmt.Println(strings.Title(clientIdentifier))
+ fmt.Println("Version:", sv.VersionWithMeta)
+ if gitCommit != "" {
+ fmt.Println("Git Commit:", gitCommit)
+ }
+ fmt.Println("Go Version:", runtime.Version())
+ fmt.Println("OS:", runtime.GOOS)
+ return nil
+}
+
+func bzzd(ctx *cli.Context) error {
+ //build a valid bzzapi.Config from all available sources:
+ //default config, file config, command line and env vars
+
+ bzzconfig, err := buildConfig(ctx)
+ if err != nil {
+ utils.Fatalf("unable to configure swarm: %v", err)
+ }
+
+ cfg := defaultNodeConfig
+
+ //pss operates on ws
+ cfg.WSModules = append(cfg.WSModules, "pss")
+
+ //geth only supports --datadir via command line
+ //in order to be consistent within swarm, if we pass --datadir via environment variable
+ //or via config file, we get the same directory for geth and swarm
+ if _, err := os.Stat(bzzconfig.Path); err == nil {
+ cfg.DataDir = bzzconfig.Path
+ }
+
+ //optionally set the bootnodes before configuring the node
+ setSwarmBootstrapNodes(ctx, &cfg)
+ //setup the ethereum node
+ utils.SetNodeConfig(ctx, &cfg)
+
+ //disable dynamic dialing from p2p/discovery
+ cfg.P2P.NoDial = true
+
+ stack, err := node.New(&cfg)
+ if err != nil {
+ utils.Fatalf("can't create node: %v", err)
+ }
+ defer stack.Close()
+
+ //a few steps need to be done after the config phase is completed,
+ //due to overriding behavior
+ err = initSwarmNode(bzzconfig, stack, ctx, &cfg)
+ if err != nil {
+ return err
+ }
+ //register BZZ as node.Service in the ethereum node
+ registerBzzService(bzzconfig, stack)
+ //start the node
+ utils.StartNode(stack)
+
+ go func() {
+ sigc := make(chan os.Signal, 1)
+ signal.Notify(sigc, syscall.SIGTERM)
+ defer signal.Stop(sigc)
+ <-sigc
+ log.Info("Got sigterm, shutting swarm down...")
+ stack.Stop()
+ }()
+
+ // add swarm bootnodes, because swarm doesn't use p2p package's discovery discv5
+ go func() {
+ s := stack.Server()
+
+ for _, n := range cfg.P2P.BootstrapNodes {
+ s.AddPeer(n)
+ }
+ }()
+
+ stack.Wait()
+ return nil
+}
+
+func registerBzzService(bzzconfig *bzzapi.Config, stack *node.Node) {
+ //define the swarm service boot function
+ boot := func(_ *node.ServiceContext) (node.Service, error) {
+ var nodeStore *mock.NodeStore
+ if bzzconfig.GlobalStoreAPI != "" {
+ // connect to global store
+ client, err := rpc.Dial(bzzconfig.GlobalStoreAPI)
+ if err != nil {
+ return nil, fmt.Errorf("global store: %v", err)
+ }
+ globalStore := mockrpc.NewGlobalStore(client)
+ // create a node store for this swarm key on global store
+ nodeStore = globalStore.NewNodeStore(common.HexToAddress(bzzconfig.BzzKey))
+ }
+ return swarm.NewSwarm(bzzconfig, nodeStore)
+ }
+ //register within the ethereum node
+ if err := stack.Register(boot); err != nil {
+ utils.Fatalf("Failed to register the Swarm service: %v", err)
+ }
+}
+
+func getAccount(bzzaccount string, ctx *cli.Context, stack *node.Node) *ecdsa.PrivateKey {
+ //an account is mandatory
+ if bzzaccount == "" {
+ utils.Fatalf(SwarmErrNoBZZAccount)
+ }
+ // Try to load the arg as a hex key file.
+ if key, err := crypto.LoadECDSA(bzzaccount); err == nil {
+ log.Info("Swarm account key loaded", "address", crypto.PubkeyToAddress(key.PublicKey))
+ return key
+ }
+ // Otherwise try getting it from the keystore.
+ am := stack.AccountManager()
+ ks := am.Backends(keystore.KeyStoreType)[0].(*keystore.KeyStore)
+
+ return decryptStoreAccount(ks, bzzaccount, utils.MakePasswordList(ctx))
+}
+
+// getPrivKey returns the private key of the specified bzzaccount
+// Used only by client commands, such as `feed`
+func getPrivKey(ctx *cli.Context) *ecdsa.PrivateKey {
+ // booting up the swarm node just as we do in bzzd action
+ bzzconfig, err := buildConfig(ctx)
+ if err != nil {
+ utils.Fatalf("unable to configure swarm: %v", err)
+ }
+ cfg := defaultNodeConfig
+ if _, err := os.Stat(bzzconfig.Path); err == nil {
+ cfg.DataDir = bzzconfig.Path
+ }
+ utils.SetNodeConfig(ctx, &cfg)
+ stack, err := node.New(&cfg)
+ if err != nil {
+ utils.Fatalf("can't create node: %v", err)
+ }
+ defer stack.Close()
+
+ return getAccount(bzzconfig.BzzAccount, ctx, stack)
+}
+
+func decryptStoreAccount(ks *keystore.KeyStore, account string, passwords []string) *ecdsa.PrivateKey {
+ var a accounts.Account
+ var err error
+ if common.IsHexAddress(account) {
+ a, err = ks.Find(accounts.Account{Address: common.HexToAddress(account)})
+ } else if ix, ixerr := strconv.Atoi(account); ixerr == nil && ix > 0 {
+ if accounts := ks.Accounts(); len(accounts) > ix {
+ a = accounts[ix]
+ } else {
+ err = fmt.Errorf("index %d higher than number of accounts %d", ix, len(accounts))
+ }
+ } else {
+ utils.Fatalf("Can't find swarm account key %s", account)
+ }
+ if err != nil {
+ utils.Fatalf("Can't find swarm account key: %v - Is the provided bzzaccount(%s) from the right datadir/Path?", err, account)
+ }
+ keyjson, err := ioutil.ReadFile(a.URL.Path)
+ if err != nil {
+ utils.Fatalf("Can't load swarm account key: %v", err)
+ }
+ for i := 0; i < 3; i++ {
+ password := getPassPhrase(fmt.Sprintf("Unlocking swarm account %s [%d/3]", a.Address.Hex(), i+1), i, passwords)
+ key, err := keystore.DecryptKey(keyjson, password)
+ if err == nil {
+ return key.PrivateKey
+ }
+ }
+ utils.Fatalf("Can't decrypt swarm account key")
+ return nil
+}
+
+// getPassPhrase retrieves the password associated with bzz account, either by fetching
+// from a list of pre-loaded passwords, or by requesting it interactively from user.
+func getPassPhrase(prompt string, i int, passwords []string) string {
+ // non-interactive
+ if len(passwords) > 0 {
+ if i < len(passwords) {
+ return passwords[i]
+ }
+ return passwords[len(passwords)-1]
+ }
+
+ // fallback to interactive mode
+ if prompt != "" {
+ fmt.Println(prompt)
+ }
+ password, err := console.Stdin.PromptPassword("Passphrase: ")
+ if err != nil {
+ utils.Fatalf("Failed to read passphrase: %v", err)
+ }
+ return password
+}
+
+// addDefaultHelpSubcommand scans through defined CLI commands and adds
+// a basic help subcommand to each
+// if a help command is already defined, it will take precedence over the default.
+func addDefaultHelpSubcommands(commands []cli.Command) {
+ for i := range commands {
+ cmd := &commands[i]
+ if cmd.Subcommands != nil {
+ cmd.Subcommands = append(cmd.Subcommands, defaultSubcommandHelp)
+ addDefaultHelpSubcommands(cmd.Subcommands)
+ }
+ }
+}
+
+func setSwarmBootstrapNodes(ctx *cli.Context, cfg *node.Config) {
+ if ctx.GlobalIsSet(utils.BootnodesFlag.Name) || ctx.GlobalIsSet(utils.BootnodesV4Flag.Name) {
+ return
+ }
+
+ cfg.P2P.BootstrapNodes = []*enode.Node{}
+
+ for _, url := range SwarmBootnodes {
+ node, err := enode.ParseV4(url)
+ if err != nil {
+ log.Error("Bootstrap URL invalid", "enode", url, "err", err)
+ }
+ cfg.P2P.BootstrapNodes = append(cfg.P2P.BootstrapNodes, node)
+ }
+
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/swarm/manifest.go b/vendor/github.com/ethereum/go-ethereum/cmd/swarm/manifest.go
new file mode 100644
index 00000000..312c72fa
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/cmd/swarm/manifest.go
@@ -0,0 +1,353 @@
+// Copyright 2017 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// go-ethereum is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with go-ethereum. If not, see .
+
+// Command MANIFEST update
+package main
+
+import (
+ "fmt"
+ "os"
+ "strings"
+
+ "github.com/ethereum/go-ethereum/cmd/utils"
+ "github.com/ethereum/go-ethereum/swarm/api"
+ swarm "github.com/ethereum/go-ethereum/swarm/api/client"
+ "gopkg.in/urfave/cli.v1"
+)
+
+var manifestCommand = cli.Command{
+ Name: "manifest",
+ CustomHelpTemplate: helpTemplate,
+ Usage: "perform operations on swarm manifests",
+ ArgsUsage: "COMMAND",
+ Description: "Updates a MANIFEST by adding/removing/updating the hash of a path.\nCOMMAND could be: add, update, remove",
+ Subcommands: []cli.Command{
+ {
+ Action: manifestAdd,
+ CustomHelpTemplate: helpTemplate,
+ Name: "add",
+ Usage: "add a new path to the manifest",
+ ArgsUsage: " ",
+ Description: "Adds a new path to the manifest",
+ },
+ {
+ Action: manifestUpdate,
+ CustomHelpTemplate: helpTemplate,
+ Name: "update",
+ Usage: "update the hash for an already existing path in the manifest",
+ ArgsUsage: " ",
+ Description: "Update the hash for an already existing path in the manifest",
+ },
+ {
+ Action: manifestRemove,
+ CustomHelpTemplate: helpTemplate,
+ Name: "remove",
+ Usage: "removes a path from the manifest",
+ ArgsUsage: " ",
+ Description: "Removes a path from the manifest",
+ },
+ },
+}
+
+// manifestAdd adds a new entry to the manifest at the given path.
+// New entry hash, the last argument, must be the hash of a manifest
+// with only one entry, which meta-data will be added to the original manifest.
+// On success, this function will print new (updated) manifest's hash.
+func manifestAdd(ctx *cli.Context) {
+ args := ctx.Args()
+ if len(args) != 3 {
+ utils.Fatalf("Need exactly three arguments ")
+ }
+
+ var (
+ mhash = args[0]
+ path = args[1]
+ hash = args[2]
+ )
+
+ bzzapi := strings.TrimRight(ctx.GlobalString(SwarmApiFlag.Name), "/")
+ client := swarm.NewClient(bzzapi)
+
+ m, _, err := client.DownloadManifest(hash)
+ if err != nil {
+ utils.Fatalf("Error downloading manifest to add: %v", err)
+ }
+ l := len(m.Entries)
+ if l == 0 {
+ utils.Fatalf("No entries in manifest %s", hash)
+ } else if l > 1 {
+ utils.Fatalf("Too many entries in manifest %s", hash)
+ }
+
+ newManifest := addEntryToManifest(client, mhash, path, m.Entries[0])
+ fmt.Println(newManifest)
+}
+
+// manifestUpdate replaces an existing entry of the manifest at the given path.
+// New entry hash, the last argument, must be the hash of a manifest
+// with only one entry, which meta-data will be added to the original manifest.
+// On success, this function will print hash of the updated manifest.
+func manifestUpdate(ctx *cli.Context) {
+ args := ctx.Args()
+ if len(args) != 3 {
+ utils.Fatalf("Need exactly three arguments ")
+ }
+
+ var (
+ mhash = args[0]
+ path = args[1]
+ hash = args[2]
+ )
+
+ bzzapi := strings.TrimRight(ctx.GlobalString(SwarmApiFlag.Name), "/")
+ client := swarm.NewClient(bzzapi)
+
+ m, _, err := client.DownloadManifest(hash)
+ if err != nil {
+ utils.Fatalf("Error downloading manifest to update: %v", err)
+ }
+ l := len(m.Entries)
+ if l == 0 {
+ utils.Fatalf("No entries in manifest %s", hash)
+ } else if l > 1 {
+ utils.Fatalf("Too many entries in manifest %s", hash)
+ }
+
+ newManifest, _, defaultEntryUpdated := updateEntryInManifest(client, mhash, path, m.Entries[0], true)
+ if defaultEntryUpdated {
+ // Print informational message to stderr
+ // allowing the user to get the new manifest hash from stdout
+ // without the need to parse the complete output.
+ fmt.Fprintln(os.Stderr, "Manifest default entry is updated, too")
+ }
+ fmt.Println(newManifest)
+}
+
+// manifestRemove removes an existing entry of the manifest at the given path.
+// On success, this function will print hash of the manifest which does not
+// contain the path.
+func manifestRemove(ctx *cli.Context) {
+ args := ctx.Args()
+ if len(args) != 2 {
+ utils.Fatalf("Need exactly two arguments ")
+ }
+
+ var (
+ mhash = args[0]
+ path = args[1]
+ )
+
+ bzzapi := strings.TrimRight(ctx.GlobalString(SwarmApiFlag.Name), "/")
+ client := swarm.NewClient(bzzapi)
+
+ newManifest := removeEntryFromManifest(client, mhash, path)
+ fmt.Println(newManifest)
+}
+
+func addEntryToManifest(client *swarm.Client, mhash, path string, entry api.ManifestEntry) string {
+ var longestPathEntry = api.ManifestEntry{}
+
+ mroot, isEncrypted, err := client.DownloadManifest(mhash)
+ if err != nil {
+ utils.Fatalf("Manifest download failed: %v", err)
+ }
+
+ // See if we path is in this Manifest or do we have to dig deeper
+ for _, e := range mroot.Entries {
+ if path == e.Path {
+ utils.Fatalf("Path %s already present, not adding anything", path)
+ } else {
+ if e.ContentType == api.ManifestType {
+ prfxlen := strings.HasPrefix(path, e.Path)
+ if prfxlen && len(path) > len(longestPathEntry.Path) {
+ longestPathEntry = e
+ }
+ }
+ }
+ }
+
+ if longestPathEntry.Path != "" {
+ // Load the child Manifest add the entry there
+ newPath := path[len(longestPathEntry.Path):]
+ newHash := addEntryToManifest(client, longestPathEntry.Hash, newPath, entry)
+
+ // Replace the hash for parent Manifests
+ newMRoot := &api.Manifest{}
+ for _, e := range mroot.Entries {
+ if longestPathEntry.Path == e.Path {
+ e.Hash = newHash
+ }
+ newMRoot.Entries = append(newMRoot.Entries, e)
+ }
+ mroot = newMRoot
+ } else {
+ // Add the entry in the leaf Manifest
+ entry.Path = path
+ mroot.Entries = append(mroot.Entries, entry)
+ }
+
+ newManifestHash, err := client.UploadManifest(mroot, isEncrypted)
+ if err != nil {
+ utils.Fatalf("Manifest upload failed: %v", err)
+ }
+ return newManifestHash
+}
+
+// updateEntryInManifest updates an existing entry o path with a new one in the manifest with provided mhash
+// finding the path recursively through all nested manifests. Argument isRoot is used for default
+// entry update detection. If the updated entry has the same hash as the default entry, then the
+// default entry in root manifest will be updated too.
+// Returned values are the new manifest hash, hash of the entry that was replaced by the new entry and
+// a a bool that is true if default entry is updated.
+func updateEntryInManifest(client *swarm.Client, mhash, path string, entry api.ManifestEntry, isRoot bool) (newManifestHash, oldHash string, defaultEntryUpdated bool) {
+ var (
+ newEntry = api.ManifestEntry{}
+ longestPathEntry = api.ManifestEntry{}
+ )
+
+ mroot, isEncrypted, err := client.DownloadManifest(mhash)
+ if err != nil {
+ utils.Fatalf("Manifest download failed: %v", err)
+ }
+
+ // See if we path is in this Manifest or do we have to dig deeper
+ for _, e := range mroot.Entries {
+ if path == e.Path {
+ newEntry = e
+ // keep the reference of the hash of the entry that should be replaced
+ // for default entry detection
+ oldHash = e.Hash
+ } else {
+ if e.ContentType == api.ManifestType {
+ prfxlen := strings.HasPrefix(path, e.Path)
+ if prfxlen && len(path) > len(longestPathEntry.Path) {
+ longestPathEntry = e
+ }
+ }
+ }
+ }
+
+ if longestPathEntry.Path == "" && newEntry.Path == "" {
+ utils.Fatalf("Path %s not present in the Manifest, not setting anything", path)
+ }
+
+ if longestPathEntry.Path != "" {
+ // Load the child Manifest add the entry there
+ newPath := path[len(longestPathEntry.Path):]
+ var newHash string
+ newHash, oldHash, _ = updateEntryInManifest(client, longestPathEntry.Hash, newPath, entry, false)
+
+ // Replace the hash for parent Manifests
+ newMRoot := &api.Manifest{}
+ for _, e := range mroot.Entries {
+ if longestPathEntry.Path == e.Path {
+ e.Hash = newHash
+ }
+ newMRoot.Entries = append(newMRoot.Entries, e)
+
+ }
+ mroot = newMRoot
+ }
+
+ // update the manifest if the new entry is found and
+ // check if default entry should be updated
+ if newEntry.Path != "" || isRoot {
+ // Replace the hash for leaf Manifest
+ newMRoot := &api.Manifest{}
+ for _, e := range mroot.Entries {
+ if newEntry.Path == e.Path {
+ entry.Path = e.Path
+ newMRoot.Entries = append(newMRoot.Entries, entry)
+ } else if isRoot && e.Path == "" && e.Hash == oldHash {
+ entry.Path = e.Path
+ newMRoot.Entries = append(newMRoot.Entries, entry)
+ defaultEntryUpdated = true
+ } else {
+ newMRoot.Entries = append(newMRoot.Entries, e)
+ }
+ }
+ mroot = newMRoot
+ }
+
+ newManifestHash, err = client.UploadManifest(mroot, isEncrypted)
+ if err != nil {
+ utils.Fatalf("Manifest upload failed: %v", err)
+ }
+ return newManifestHash, oldHash, defaultEntryUpdated
+}
+
+func removeEntryFromManifest(client *swarm.Client, mhash, path string) string {
+ var (
+ entryToRemove = api.ManifestEntry{}
+ longestPathEntry = api.ManifestEntry{}
+ )
+
+ mroot, isEncrypted, err := client.DownloadManifest(mhash)
+ if err != nil {
+ utils.Fatalf("Manifest download failed: %v", err)
+ }
+
+ // See if we path is in this Manifest or do we have to dig deeper
+ for _, entry := range mroot.Entries {
+ if path == entry.Path {
+ entryToRemove = entry
+ } else {
+ if entry.ContentType == api.ManifestType {
+ prfxlen := strings.HasPrefix(path, entry.Path)
+ if prfxlen && len(path) > len(longestPathEntry.Path) {
+ longestPathEntry = entry
+ }
+ }
+ }
+ }
+
+ if longestPathEntry.Path == "" && entryToRemove.Path == "" {
+ utils.Fatalf("Path %s not present in the Manifest, not removing anything", path)
+ }
+
+ if longestPathEntry.Path != "" {
+ // Load the child Manifest remove the entry there
+ newPath := path[len(longestPathEntry.Path):]
+ newHash := removeEntryFromManifest(client, longestPathEntry.Hash, newPath)
+
+ // Replace the hash for parent Manifests
+ newMRoot := &api.Manifest{}
+ for _, entry := range mroot.Entries {
+ if longestPathEntry.Path == entry.Path {
+ entry.Hash = newHash
+ }
+ newMRoot.Entries = append(newMRoot.Entries, entry)
+ }
+ mroot = newMRoot
+ }
+
+ if entryToRemove.Path != "" {
+ // remove the entry in this Manifest
+ newMRoot := &api.Manifest{}
+ for _, entry := range mroot.Entries {
+ if entryToRemove.Path != entry.Path {
+ newMRoot.Entries = append(newMRoot.Entries, entry)
+ }
+ }
+ mroot = newMRoot
+ }
+
+ newManifestHash, err := client.UploadManifest(mroot, isEncrypted)
+ if err != nil {
+ utils.Fatalf("Manifest upload failed: %v", err)
+ }
+ return newManifestHash
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/swarm/mimegen/generator.go b/vendor/github.com/ethereum/go-ethereum/cmd/swarm/mimegen/generator.go
new file mode 100644
index 00000000..68f9e306
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/cmd/swarm/mimegen/generator.go
@@ -0,0 +1,124 @@
+// Copyright 2018 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// go-ethereum is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with go-ethereum. If not, see .
+package main
+
+// Standard "mime" package rely on system-settings, see mime.osInitMime
+// Swarm will run on many OS/Platform/Docker and must behave similar
+// This command generates code to add common mime types based on mime.types file
+//
+// mime.types file provided by mailcap, which follow https://www.iana.org/assignments/media-types/media-types.xhtml
+//
+// Get last version of mime.types file by:
+// docker run --rm -v $(pwd):/tmp alpine:edge /bin/sh -c "apk add -U mailcap; mv /etc/mime.types /tmp"
+
+import (
+ "bufio"
+ "bytes"
+ "flag"
+ "html/template"
+ "io/ioutil"
+ "strings"
+
+ "log"
+)
+
+var (
+ typesFlag = flag.String("types", "", "Input mime.types file")
+ packageFlag = flag.String("package", "", "Golang package in output file")
+ outFlag = flag.String("out", "", "Output file name for the generated mime types")
+)
+
+type mime struct {
+ Name string
+ Exts []string
+}
+
+type templateParams struct {
+ PackageName string
+ Mimes []mime
+}
+
+func main() {
+ // Parse and ensure all needed inputs are specified
+ flag.Parse()
+ if *typesFlag == "" {
+ log.Fatalf("--types is required")
+ }
+ if *packageFlag == "" {
+ log.Fatalf("--types is required")
+ }
+ if *outFlag == "" {
+ log.Fatalf("--out is required")
+ }
+
+ params := templateParams{
+ PackageName: *packageFlag,
+ }
+
+ types, err := ioutil.ReadFile(*typesFlag)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ scanner := bufio.NewScanner(bytes.NewReader(types))
+ for scanner.Scan() {
+ txt := scanner.Text()
+ if strings.HasPrefix(txt, "#") || len(txt) == 0 {
+ continue
+ }
+ parts := strings.Fields(txt)
+ if len(parts) == 1 {
+ continue
+ }
+ params.Mimes = append(params.Mimes, mime{parts[0], parts[1:]})
+ }
+
+ if err = scanner.Err(); err != nil {
+ log.Fatal(err)
+ }
+
+ result := bytes.NewBuffer([]byte{})
+
+ if err := template.Must(template.New("_").Parse(tpl)).Execute(result, params); err != nil {
+ log.Fatal(err)
+ }
+
+ if err := ioutil.WriteFile(*outFlag, result.Bytes(), 0600); err != nil {
+ log.Fatal(err)
+ }
+}
+
+var tpl = `// Code generated by github.com/ethereum/go-ethereum/cmd/swarm/mimegen. DO NOT EDIT.
+
+package {{ .PackageName }}
+
+import "mime"
+func init() {
+ var mimeTypes = map[string]string{
+{{- range .Mimes -}}
+ {{ $name := .Name -}}
+ {{- range .Exts }}
+ ".{{ . }}": "{{ $name | html }}",
+ {{- end }}
+{{- end }}
+ }
+ for ext, name := range mimeTypes {
+ if err := mime.AddExtensionType(ext, name); err != nil {
+ panic(err)
+ }
+ }
+}
+`
diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/swarm/mimegen/mime.types b/vendor/github.com/ethereum/go-ethereum/cmd/swarm/mimegen/mime.types
new file mode 100644
index 00000000..1bdf2114
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/cmd/swarm/mimegen/mime.types
@@ -0,0 +1,1828 @@
+# This is a comment. I love comments. -*- indent-tabs-mode: t -*-
+
+# This file controls what Internet media types are sent to the client for
+# given file extension(s). Sending the correct media type to the client
+# is important so they know how to handle the content of the file.
+# Extra types can either be added here or by using an AddType directive
+# in your config files. For more information about Internet media types,
+# please read RFC 2045, 2046, 2047, 2048, and 2077. The Internet media type
+# registry is at .
+
+# IANA types
+
+# MIME type Extensions
+application/1d-interleaved-parityfec
+application/3gpdash-qoe-report+xml
+application/3gpp-ims+xml
+application/A2L a2l
+application/activemessage
+application/alto-costmap+json
+application/alto-costmapfilter+json
+application/alto-directory+json
+application/alto-endpointcost+json
+application/alto-endpointcostparams+json
+application/alto-endpointprop+json
+application/alto-endpointpropparams+json
+application/alto-error+json
+application/alto-networkmap+json
+application/alto-networkmapfilter+json
+application/AML aml
+application/andrew-inset ez
+application/applefile
+application/ATF atf
+application/ATFX atfx
+application/ATXML atxml
+application/atom+xml atom
+application/atomcat+xml atomcat
+application/atomdeleted+xml atomdeleted
+application/atomicmail
+application/atomsvc+xml atomsvc
+application/auth-policy+xml apxml
+application/bacnet-xdd+zip xdd
+application/batch-SMTP
+application/beep+xml
+application/calendar+json
+application/calendar+xml xcs
+application/call-completion
+application/cals-1840
+application/cbor cbor
+application/ccmp+xml ccmp
+application/ccxml+xml ccxml
+application/CDFX+XML cdfx
+application/cdmi-capability cdmia
+application/cdmi-container cdmic
+application/cdmi-domain cdmid
+application/cdmi-object cdmio
+application/cdmi-queue cdmiq
+application/cdni
+application/CEA cea
+application/cea-2018+xml
+application/cellml+xml cellml cml
+application/cfw
+application/clue_info+xml clue
+application/cms cmsc
+application/cnrp+xml
+application/coap-group+json
+application/coap-payload
+application/commonground
+application/conference-info+xml
+application/cpl+xml cpl
+application/cose
+application/cose-key
+application/cose-key-set
+application/csrattrs csrattrs
+application/csta+xml
+application/CSTAdata+xml
+application/csvm+json
+application/cybercash
+application/dash+xml mpd
+application/dashdelta mpdd
+application/davmount+xml davmount
+application/dca-rft
+application/DCD dcd
+application/dec-dx
+application/dialog-info+xml
+application/dicom dcm
+application/dicom+json
+application/dicom+xml
+application/DII dii
+application/DIT dit
+application/dns
+application/dskpp+xml xmls
+application/dssc+der dssc
+application/dssc+xml xdssc
+application/dvcs dvc
+application/ecmascript es
+application/EDI-Consent
+application/EDI-X12
+application/EDIFACT
+application/efi efi
+application/EmergencyCallData.Comment+xml
+application/EmergencyCallData.Control+xml
+application/EmergencyCallData.DeviceInfo+xml
+application/EmergencyCallData.eCall.MSD
+application/EmergencyCallData.ProviderInfo+xml
+application/EmergencyCallData.ServiceInfo+xml
+application/EmergencyCallData.SubscriberInfo+xml
+application/EmergencyCallData.VEDS+xml
+application/emma+xml emma
+application/emotionml+xml emotionml
+application/encaprtp
+application/epp+xml
+application/epub+zip epub
+application/eshop
+application/exi exi
+application/fastinfoset finf
+application/fastsoap
+application/fdt+xml fdt
+# fits, fit, fts: image/fits
+application/fits
+# application/font-sfnt deprecated in favor of font/sfnt
+application/font-tdpfr pfr
+# application/font-woff deprecated in favor of font/woff
+application/framework-attributes+xml
+application/geo+json geojson
+application/geo+json-seq
+application/gml+xml gml
+application/gzip gz tgz
+application/H224
+application/held+xml
+application/http
+application/hyperstudio stk
+application/ibe-key-request+xml
+application/ibe-pkg-reply+xml
+application/ibe-pp-data
+application/iges
+application/im-iscomposing+xml
+application/index
+application/index.cmd
+application/index.obj
+application/index.response
+application/index.vnd
+application/inkml+xml ink inkml
+application/iotp
+application/ipfix ipfix
+application/ipp
+application/isup
+application/its+xml its
+application/javascript js
+application/jose
+application/jose+json
+application/jrd+json jrd
+application/json json
+application/json-patch+json json-patch
+application/json-seq
+application/jwk+json
+application/jwk-set+json
+application/jwt
+application/kpml-request+xml
+application/kpml-response+xml
+application/ld+json jsonld
+application/lgr+xml lgr
+application/link-format wlnk
+application/load-control+xml
+application/lost+xml lostxml
+application/lostsync+xml lostsyncxml
+application/LXF lxf
+application/mac-binhex40 hqx
+application/macwriteii
+application/mads+xml mads
+application/marc mrc
+application/marcxml+xml mrcx
+application/mathematica nb ma mb
+application/mathml-content+xml
+application/mathml-presentation+xml
+application/mathml+xml mml
+application/mbms-associated-procedure-description+xml
+application/mbms-deregister+xml
+application/mbms-envelope+xml
+application/mbms-msk-response+xml
+application/mbms-msk+xml
+application/mbms-protection-description+xml
+application/mbms-reception-report+xml
+application/mbms-register-response+xml
+application/mbms-register+xml
+application/mbms-schedule+xml
+application/mbms-user-service-description+xml
+application/mbox mbox
+application/media_control+xml
+# mpf: text/vnd.ms-mediapackage
+application/media-policy-dataset+xml
+application/mediaservercontrol+xml
+application/merge-patch+json
+application/metalink4+xml meta4
+application/mets+xml mets
+application/MF4 mf4
+application/mikey
+application/mods+xml mods
+application/moss-keys
+application/moss-signature
+application/mosskey-data
+application/mosskey-request
+application/mp21 m21 mp21
+# mp4, mpg4: video/mp4, see RFC 4337
+application/mp4
+application/mpeg4-generic
+application/mpeg4-iod
+application/mpeg4-iod-xmt
+# xdf: application/xcap-diff+xml
+application/mrb-consumer+xml
+application/mrb-publish+xml
+application/msc-ivr+xml
+application/msc-mixer+xml
+application/msword doc
+application/mud+json
+application/mxf mxf
+application/n-quads nq
+application/n-triples nt
+application/nasdata
+application/news-checkgroups
+application/news-groupinfo
+application/news-transmission
+application/nlsml+xml
+application/nss
+application/ocsp-request orq
+application/ocsp-response ors
+application/octet-stream bin lha lzh exe class so dll img iso
+application/oda oda
+application/ODX odx
+application/oebps-package+xml opf
+application/ogg ogx
+application/oxps oxps
+application/p2p-overlay+xml relo
+application/parityfec
+# xer: application/xcap-error+xml
+application/patch-ops-error+xml
+application/pdf pdf
+application/PDX pdx
+application/pgp-encrypted pgp
+application/pgp-keys
+application/pgp-signature sig
+application/pidf-diff+xml
+application/pidf+xml
+application/pkcs10 p10
+application/pkcs12 p12 pfx
+application/pkcs7-mime p7m p7c
+application/pkcs7-signature p7s
+application/pkcs8 p8
+# ac: application/vnd.nokia.n-gage.ac+xml
+application/pkix-attr-cert
+application/pkix-cert cer
+application/pkix-crl crl
+application/pkix-pkipath pkipath
+application/pkixcmp pki
+application/pls+xml pls
+application/poc-settings+xml
+application/postscript ps eps ai
+application/ppsp-tracker+json
+application/problem+json
+application/problem+xml
+application/provenance+xml provx
+application/prs.alvestrand.titrax-sheet
+application/prs.cww cw cww
+application/prs.hpub+zip hpub
+application/prs.nprend rnd rct
+application/prs.plucker
+application/prs.rdf-xml-crypt rdf-crypt
+application/prs.xsf+xml xsf
+application/pskc+xml pskcxml
+application/qsig
+application/raptorfec
+application/rdap+json
+application/rdf+xml rdf
+application/reginfo+xml rif
+application/relax-ng-compact-syntax rnc
+application/remote-printing
+application/reputon+json
+application/resource-lists-diff+xml rld
+application/resource-lists+xml rl
+application/rfc+xml rfcxml
+application/riscos
+application/rlmi+xml
+application/rls-services+xml rs
+application/rpki-ghostbusters gbr
+application/rpki-manifest mft
+application/rpki-publication
+application/rpki-roa roa
+application/rpki-updown
+application/rtf rtf
+application/rtploopback
+application/rtx
+application/samlassertion+xml
+application/samlmetadata+xml
+application/sbml+xml
+application/scaip+xml
+# scm: application/vnd.lotus-screencam
+application/scim+json scim
+application/scvp-cv-request scq
+application/scvp-cv-response scs
+application/scvp-vp-request spq
+application/scvp-vp-response spp
+application/sdp sdp
+application/sep+xml
+application/sep-exi
+application/session-info
+application/set-payment
+application/set-payment-initiation
+application/set-registration
+application/set-registration-initiation
+application/sgml
+application/sgml-open-catalog soc
+application/shf+xml shf
+application/sieve siv sieve
+application/simple-filter+xml cl
+application/simple-message-summary
+application/simpleSymbolContainer
+application/slate
+# application/smil obsoleted by application/smil+xml
+application/smil+xml smil smi sml
+application/smpte336m
+application/soap+fastinfoset
+application/soap+xml
+application/sparql-query rq
+application/sparql-results+xml srx
+application/spirits-event+xml
+application/sql sql
+application/srgs gram
+application/srgs+xml grxml
+application/sru+xml sru
+application/ssml+xml ssml
+application/tamp-apex-update tau
+application/tamp-apex-update-confirm auc
+application/tamp-community-update tcu
+application/tamp-community-update-confirm cuc
+application/tamp-error ter
+application/tamp-sequence-adjust tsa
+application/tamp-sequence-adjust-confirm sac
+# tsq: application/timestamp-query
+application/tamp-status-query
+# tsr: application/timestamp-reply
+application/tamp-status-response
+application/tamp-update tur
+application/tamp-update-confirm tuc
+application/tei+xml tei teiCorpus odd
+application/thraud+xml tfi
+application/timestamp-query tsq
+application/timestamp-reply tsr
+application/timestamped-data tsd
+application/trig trig
+application/ttml+xml ttml
+application/tve-trigger
+application/ulpfec
+application/urc-grpsheet+xml gsheet
+application/urc-ressheet+xml rsheet
+application/urc-targetdesc+xml td
+application/urc-uisocketdesc+xml uis
+application/vcard+json
+application/vcard+xml
+application/vemmi
+application/vnd.3gpp.access-transfer-events+xml
+application/vnd.3gpp.bsf+xml
+application/vnd.3gpp.mid-call+xml
+application/vnd.3gpp.pic-bw-large plb
+application/vnd.3gpp.pic-bw-small psb
+application/vnd.3gpp.pic-bw-var pvb
+application/vnd.3gpp-prose+xml
+application/vnd.3gpp-prose-pc3ch+xml
+# sms: application/vnd.3gpp2.sms
+application/vnd.3gpp.sms
+application/vnd.3gpp.sms+xml
+application/vnd.3gpp.srvcc-ext+xml
+application/vnd.3gpp.SRVCC-info+xml
+application/vnd.3gpp.state-and-event-info+xml
+application/vnd.3gpp.ussd+xml
+application/vnd.3gpp2.bcmcsinfo+xml
+application/vnd.3gpp2.sms sms
+application/vnd.3gpp2.tcap tcap
+application/vnd.3lightssoftware.imagescal imgcal
+application/vnd.3M.Post-it-Notes pwn
+application/vnd.accpac.simply.aso aso
+application/vnd.accpac.simply.imp imp
+application/vnd.acucobol acu
+application/vnd.acucorp atc acutc
+application/vnd.adobe.flash.movie swf
+application/vnd.adobe.formscentral.fcdt fcdt
+application/vnd.adobe.fxp fxp fxpl
+application/vnd.adobe.partial-upload
+application/vnd.adobe.xdp+xml xdp
+application/vnd.adobe.xfdf xfdf
+application/vnd.aether.imp
+application/vnd.ah-barcode
+application/vnd.ahead.space ahead
+application/vnd.airzip.filesecure.azf azf
+application/vnd.airzip.filesecure.azs azs
+application/vnd.amazon.mobi8-ebook azw3
+application/vnd.americandynamics.acc acc
+application/vnd.amiga.ami ami
+application/vnd.amundsen.maze+xml
+application/vnd.anki apkg
+application/vnd.anser-web-certificate-issue-initiation cii
+# Not in IANA listing, but is on FTP site?
+application/vnd.anser-web-funds-transfer-initiation fti
+# atx: audio/ATRAC-X
+application/vnd.antix.game-component
+application/vnd.apache.thrift.binary
+application/vnd.apache.thrift.compact
+application/vnd.apache.thrift.json
+application/vnd.api+json
+application/vnd.apothekende.reservation+json
+application/vnd.apple.installer+xml dist distz pkg mpkg
+# m3u: audio/x-mpegurl for now
+application/vnd.apple.mpegurl m3u8
+# application/vnd.arastra.swi obsoleted by application/vnd.aristanetworks.swi
+application/vnd.aristanetworks.swi swi
+application/vnd.artsquare
+application/vnd.astraea-software.iota iota
+application/vnd.audiograph aep
+application/vnd.autopackage package
+application/vnd.avistar+xml
+application/vnd.balsamiq.bmml+xml bmml
+application/vnd.balsamiq.bmpr bmpr
+application/vnd.bekitzur-stech+json
+application/vnd.bint.med-content
+application/vnd.biopax.rdf+xml
+application/vnd.blueice.multipass mpm
+application/vnd.bluetooth.ep.oob ep
+application/vnd.bluetooth.le.oob le
+application/vnd.bmi bmi
+application/vnd.businessobjects rep
+application/vnd.cab-jscript
+application/vnd.canon-cpdl
+application/vnd.canon-lips
+application/vnd.capasystems-pg+json
+application/vnd.cendio.thinlinc.clientconf tlclient
+application/vnd.century-systems.tcp_stream
+application/vnd.chemdraw+xml cdxml
+application/vnd.chess-pgn pgn
+application/vnd.chipnuts.karaoke-mmd mmd
+application/vnd.cinderella cdy
+application/vnd.cirpack.isdn-ext
+application/vnd.citationstyles.style+xml csl
+application/vnd.claymore cla
+application/vnd.cloanto.rp9 rp9
+application/vnd.clonk.c4group c4g c4d c4f c4p c4u
+application/vnd.cluetrust.cartomobile-config c11amc
+application/vnd.cluetrust.cartomobile-config-pkg c11amz
+application/vnd.coffeescript coffee
+application/vnd.collection+json
+application/vnd.collection.doc+json
+application/vnd.collection.next+json
+application/vnd.comicbook+zip cbz
+# icc: application/vnd.iccprofile
+application/vnd.commerce-battelle ica icf icd ic0 ic1 ic2 ic3 ic4 ic5 ic6 ic7 ic8
+application/vnd.commonspace csp cst
+application/vnd.contact.cmsg cdbcmsg
+application/vnd.coreos.ignition+json ign ignition
+application/vnd.cosmocaller cmc
+application/vnd.crick.clicker clkx
+application/vnd.crick.clicker.keyboard clkk
+application/vnd.crick.clicker.palette clkp
+application/vnd.crick.clicker.template clkt
+application/vnd.crick.clicker.wordbank clkw
+application/vnd.criticaltools.wbs+xml wbs
+application/vnd.ctc-posml pml
+application/vnd.ctct.ws+xml
+application/vnd.cups-pdf
+application/vnd.cups-postscript
+application/vnd.cups-ppd ppd
+application/vnd.cups-raster
+application/vnd.cups-raw
+application/vnd.curl curl
+application/vnd.cyan.dean.root+xml
+application/vnd.cybank
+application/vnd.d2l.coursepackage1p0+zip
+application/vnd.dart dart
+application/vnd.data-vision.rdz rdz
+application/vnd.datapackage+json
+application/vnd.dataresource+json
+application/vnd.debian.binary-package deb udeb
+application/vnd.dece.data uvf uvvf uvd uvvd
+application/vnd.dece.ttml+xml uvt uvvt
+application/vnd.dece.unspecified uvx uvvx
+application/vnd.dece.zip uvz uvvz
+application/vnd.denovo.fcselayout-link fe_launch
+application/vnd.desmume.movie dsm
+application/vnd.dir-bi.plate-dl-nosuffix
+application/vnd.dm.delegation+xml
+application/vnd.dna dna
+application/vnd.document+json docjson
+application/vnd.dolby.mobile.1
+application/vnd.dolby.mobile.2
+application/vnd.doremir.scorecloud-binary-document scld
+application/vnd.dpgraph dpg mwc dpgraph
+application/vnd.dreamfactory dfac
+application/vnd.drive+json
+application/vnd.dtg.local
+application/vnd.dtg.local.flash fla
+application/vnd.dtg.local.html
+application/vnd.dvb.ait ait
+# class: application/octet-stream
+application/vnd.dvb.dvbj
+application/vnd.dvb.esgcontainer
+application/vnd.dvb.ipdcdftnotifaccess
+application/vnd.dvb.ipdcesgaccess
+application/vnd.dvb.ipdcesgaccess2
+application/vnd.dvb.ipdcesgpdd
+application/vnd.dvb.ipdcroaming
+application/vnd.dvb.iptv.alfec-base
+application/vnd.dvb.iptv.alfec-enhancement
+application/vnd.dvb.notif-aggregate-root+xml
+application/vnd.dvb.notif-container+xml
+application/vnd.dvb.notif-generic+xml
+application/vnd.dvb.notif-ia-msglist+xml
+application/vnd.dvb.notif-ia-registration-request+xml
+application/vnd.dvb.notif-ia-registration-response+xml
+application/vnd.dvb.notif-init+xml
+# pfr: application/font-tdpfr
+application/vnd.dvb.pfr
+application/vnd.dvb.service svc
+# dxr: application/x-director
+application/vnd.dxr
+application/vnd.dynageo geo
+application/vnd.dzr dzr
+application/vnd.easykaraoke.cdgdownload
+application/vnd.ecdis-update
+application/vnd.ecowin.chart mag
+application/vnd.ecowin.filerequest
+application/vnd.ecowin.fileupdate
+application/vnd.ecowin.series
+application/vnd.ecowin.seriesrequest
+application/vnd.ecowin.seriesupdate
+# img: application/octet-stream
+application/vnd.efi-img
+# iso: application/octet-stream
+application/vnd.efi-iso
+application/vnd.enliven nml
+application/vnd.enphase.envoy
+application/vnd.eprints.data+xml
+application/vnd.epson.esf esf
+application/vnd.epson.msf msf
+application/vnd.epson.quickanime qam
+application/vnd.epson.salt slt
+application/vnd.epson.ssf ssf
+application/vnd.ericsson.quickcall qcall qca
+application/vnd.espass-espass+zip espass
+application/vnd.eszigno3+xml es3 et3
+application/vnd.etsi.aoc+xml
+application/vnd.etsi.asic-e+zip asice sce
+# scs: application/scvp-cv-response
+application/vnd.etsi.asic-s+zip asics
+application/vnd.etsi.cug+xml
+application/vnd.etsi.iptvcommand+xml
+application/vnd.etsi.iptvdiscovery+xml
+application/vnd.etsi.iptvprofile+xml
+application/vnd.etsi.iptvsad-bc+xml
+application/vnd.etsi.iptvsad-cod+xml
+application/vnd.etsi.iptvsad-npvr+xml
+application/vnd.etsi.iptvservice+xml
+application/vnd.etsi.iptvsync+xml
+application/vnd.etsi.iptvueprofile+xml
+application/vnd.etsi.mcid+xml
+application/vnd.etsi.mheg5
+application/vnd.etsi.overload-control-policy-dataset+xml
+application/vnd.etsi.pstn+xml
+application/vnd.etsi.sci+xml
+application/vnd.etsi.simservs+xml
+application/vnd.etsi.timestamp-token tst
+application/vnd.etsi.tsl.der
+application/vnd.etsi.tsl+xml
+application/vnd.eudora.data
+application/vnd.ezpix-album ez2
+application/vnd.ezpix-package ez3
+application/vnd.f-secure.mobile
+application/vnd.fastcopy-disk-image dim
+application/vnd.fdf fdf
+application/vnd.fdsn.mseed msd mseed
+application/vnd.fdsn.seed seed dataless
+application/vnd.ffsns
+application/vnd.filmit.zfc zfc
+# all extensions: application/vnd.hbci
+application/vnd.fints
+application/vnd.firemonkeys.cloudcell
+application/vnd.FloGraphIt gph
+application/vnd.fluxtime.clip ftc
+application/vnd.font-fontforge-sfd sfd
+application/vnd.framemaker fm
+application/vnd.frogans.fnc fnc
+application/vnd.frogans.ltf ltf
+application/vnd.fsc.weblaunch fsc
+application/vnd.fujitsu.oasys oas
+application/vnd.fujitsu.oasys2 oa2
+application/vnd.fujitsu.oasys3 oa3
+application/vnd.fujitsu.oasysgp fg5
+application/vnd.fujitsu.oasysprs bh2
+application/vnd.fujixerox.ART-EX
+application/vnd.fujixerox.ART4
+application/vnd.fujixerox.ddd ddd
+application/vnd.fujixerox.docuworks xdw
+application/vnd.fujixerox.docuworks.binder xbd
+application/vnd.fujixerox.docuworks.container xct
+application/vnd.fujixerox.HBPL
+application/vnd.fut-misnet
+application/vnd.fuzzysheet fzs
+application/vnd.genomatix.tuxedo txd
+# application/vnd.geo+json obsoleted by application/geo+json
+application/vnd.geocube+xml g3 g³
+application/vnd.geogebra.file ggb
+application/vnd.geogebra.tool ggt
+application/vnd.geometry-explorer gex gre
+application/vnd.geonext gxt
+application/vnd.geoplan g2w
+application/vnd.geospace g3w
+# gbr: application/rpki-ghostbusters
+application/vnd.gerber
+application/vnd.globalplatform.card-content-mgt
+application/vnd.globalplatform.card-content-mgt-response
+application/vnd.gmx gmx
+application/vnd.google-earth.kml+xml kml
+application/vnd.google-earth.kmz kmz
+application/vnd.gov.sk.e-form+xml
+application/vnd.gov.sk.e-form+zip
+application/vnd.gov.sk.xmldatacontainer+xml
+application/vnd.grafeq gqf gqs
+application/vnd.gridmp
+application/vnd.groove-account gac
+application/vnd.groove-help ghf
+application/vnd.groove-identity-message gim
+application/vnd.groove-injector grv
+application/vnd.groove-tool-message gtm
+application/vnd.groove-tool-template tpl
+application/vnd.groove-vcard vcg
+application/vnd.hal+json
+application/vnd.hal+xml hal
+application/vnd.HandHeld-Entertainment+xml zmm
+application/vnd.hbci hbci hbc kom upa pkd bpd
+application/vnd.hc+json
+# rep: application/vnd.businessobjects
+application/vnd.hcl-bireports
+application/vnd.hdt hdt
+application/vnd.heroku+json
+application/vnd.hhe.lesson-player les
+application/vnd.hp-HPGL hpgl
+application/vnd.hp-hpid hpi hpid
+application/vnd.hp-hps hps
+application/vnd.hp-jlyt jlt
+application/vnd.hp-PCL pcl
+application/vnd.hp-PCLXL
+application/vnd.httphone
+application/vnd.hydrostatix.sof-data sfd-hdstx
+application/vnd.hyperdrive+json
+application/vnd.hzn-3d-crossword x3d
+application/vnd.ibm.afplinedata
+application/vnd.ibm.electronic-media emm
+application/vnd.ibm.MiniPay mpy
+application/vnd.ibm.modcap list3820 listafp afp pseg3820
+application/vnd.ibm.rights-management irm
+application/vnd.ibm.secure-container sc
+application/vnd.iccprofile icc icm
+application/vnd.ieee.1905 1905.1
+application/vnd.igloader igl
+application/vnd.imagemeter.folder+zip imf
+application/vnd.imagemeter.image+zip imi
+application/vnd.immervision-ivp ivp
+application/vnd.immervision-ivu ivu
+application/vnd.ims.imsccv1p1 imscc
+application/vnd.ims.imsccv1p2
+application/vnd.ims.imsccv1p3
+application/vnd.ims.lis.v2.result+json
+application/vnd.ims.lti.v2.toolconsumerprofile+json
+application/vnd.ims.lti.v2.toolproxy.id+json
+application/vnd.ims.lti.v2.toolproxy+json
+application/vnd.ims.lti.v2.toolsettings+json
+application/vnd.ims.lti.v2.toolsettings.simple+json
+application/vnd.informedcontrol.rms+xml
+# application/vnd.informix-visionary obsoleted by application/vnd.visionary
+application/vnd.infotech.project
+application/vnd.infotech.project+xml
+application/vnd.innopath.wamp.notification
+application/vnd.insors.igm igm
+application/vnd.intercon.formnet xpw xpx
+application/vnd.intergeo i2g
+application/vnd.intertrust.digibox
+application/vnd.intertrust.nncp
+application/vnd.intu.qbo qbo
+application/vnd.intu.qfx qfx
+application/vnd.iptc.g2.catalogitem+xml
+application/vnd.iptc.g2.conceptitem+xml
+application/vnd.iptc.g2.knowledgeitem+xml
+application/vnd.iptc.g2.newsitem+xml
+application/vnd.iptc.g2.newsmessage+xml
+application/vnd.iptc.g2.packageitem+xml
+application/vnd.iptc.g2.planningitem+xml
+application/vnd.ipunplugged.rcprofile rcprofile
+application/vnd.irepository.package+xml irp
+application/vnd.is-xpr xpr
+application/vnd.isac.fcs fcs
+application/vnd.jam jam
+application/vnd.japannet-directory-service
+application/vnd.japannet-jpnstore-wakeup
+application/vnd.japannet-payment-wakeup
+application/vnd.japannet-registration
+application/vnd.japannet-registration-wakeup
+application/vnd.japannet-setstore-wakeup
+application/vnd.japannet-verification
+application/vnd.japannet-verification-wakeup
+application/vnd.jcp.javame.midlet-rms rms
+application/vnd.jisp jisp
+application/vnd.joost.joda-archive joda
+application/vnd.jsk.isdn-ngn
+application/vnd.kahootz ktz ktr
+application/vnd.kde.karbon karbon
+application/vnd.kde.kchart chrt
+application/vnd.kde.kformula kfo
+application/vnd.kde.kivio flw
+application/vnd.kde.kontour kon
+application/vnd.kde.kpresenter kpr kpt
+application/vnd.kde.kspread ksp
+application/vnd.kde.kword kwd kwt
+application/vnd.kenameaapp htke
+application/vnd.kidspiration kia
+application/vnd.Kinar kne knp sdf
+application/vnd.koan skp skd skm skt
+application/vnd.kodak-descriptor sse
+application/vnd.las.las+json lasjson
+application/vnd.las.las+xml lasxml
+application/vnd.liberty-request+xml
+application/vnd.llamagraphics.life-balance.desktop lbd
+application/vnd.llamagraphics.life-balance.exchange+xml lbe
+application/vnd.lotus-1-2-3 123 wk4 wk3 wk1
+application/vnd.lotus-approach apr vew
+application/vnd.lotus-freelance prz pre
+application/vnd.lotus-notes nsf ntf ndl ns4 ns3 ns2 nsh nsg
+application/vnd.lotus-organizer or3 or2 org
+application/vnd.lotus-screencam scm
+application/vnd.lotus-wordpro lwp sam
+application/vnd.macports.portpkg portpkg
+application/vnd.mapbox-vector-tile mvt
+application/vnd.marlin.drm.actiontoken+xml
+application/vnd.marlin.drm.conftoken+xml
+application/vnd.marlin.drm.license+xml
+application/vnd.marlin.drm.mdcf mdc
+application/vnd.mason+json
+application/vnd.maxmind.maxmind-db mmdb
+application/vnd.mcd mcd
+application/vnd.medcalcdata mc1
+application/vnd.mediastation.cdkey cdkey
+application/vnd.meridian-slingshot
+application/vnd.MFER mwf
+application/vnd.mfmp mfm
+application/vnd.micro+json
+application/vnd.micrografx.flo flo
+application/vnd.micrografx.igx igx
+application/vnd.microsoft.portable-executable
+application/vnd.microsoft.windows.thumbnail-cache
+application/vnd.miele+json
+application/vnd.mif mif
+application/vnd.minisoft-hp3000-save
+application/vnd.mitsubishi.misty-guard.trustweb
+application/vnd.Mobius.DAF daf
+application/vnd.Mobius.DIS dis
+application/vnd.Mobius.MBK mbk
+application/vnd.Mobius.MQY mqy
+application/vnd.Mobius.MSL msl
+application/vnd.Mobius.PLC plc
+application/vnd.Mobius.TXF txf
+application/vnd.mophun.application mpn
+application/vnd.mophun.certificate mpc
+application/vnd.motorola.flexsuite
+application/vnd.motorola.flexsuite.adsi
+application/vnd.motorola.flexsuite.fis
+application/vnd.motorola.flexsuite.gotap
+application/vnd.motorola.flexsuite.kmr
+application/vnd.motorola.flexsuite.ttc
+application/vnd.motorola.flexsuite.wem
+application/vnd.motorola.iprm
+application/vnd.mozilla.xul+xml xul
+application/vnd.ms-3mfdocument 3mf
+application/vnd.ms-artgalry cil
+application/vnd.ms-asf asf
+application/vnd.ms-cab-compressed cab
+application/vnd.ms-excel xls xlm xla xlc xlt xlw
+application/vnd.ms-excel.template.macroEnabled.12 xltm
+application/vnd.ms-excel.addin.macroEnabled.12 xlam
+application/vnd.ms-excel.sheet.binary.macroEnabled.12 xlsb
+application/vnd.ms-excel.sheet.macroEnabled.12 xlsm
+application/vnd.ms-fontobject eot
+application/vnd.ms-htmlhelp chm
+application/vnd.ms-ims ims
+application/vnd.ms-lrm lrm
+application/vnd.ms-office.activeX+xml
+application/vnd.ms-officetheme thmx
+application/vnd.ms-playready.initiator+xml
+application/vnd.ms-powerpoint ppt pps pot
+application/vnd.ms-powerpoint.addin.macroEnabled.12 ppam
+application/vnd.ms-powerpoint.presentation.macroEnabled.12 pptm
+application/vnd.ms-powerpoint.slide.macroEnabled.12 sldm
+application/vnd.ms-powerpoint.slideshow.macroEnabled.12 ppsm
+application/vnd.ms-powerpoint.template.macroEnabled.12 potm
+application/vnd.ms-PrintDeviceCapabilities+xml
+application/vnd.ms-PrintSchemaTicket+xml
+application/vnd.ms-project mpp mpt
+application/vnd.ms-tnef tnef tnf
+application/vnd.ms-windows.devicepairing
+application/vnd.ms-windows.nwprinting.oob
+application/vnd.ms-windows.printerpairing
+application/vnd.ms-windows.wsd.oob
+application/vnd.ms-wmdrm.lic-chlg-req
+application/vnd.ms-wmdrm.lic-resp
+application/vnd.ms-wmdrm.meter-chlg-req
+application/vnd.ms-wmdrm.meter-resp
+application/vnd.ms-word.document.macroEnabled.12 docm
+application/vnd.ms-word.template.macroEnabled.12 dotm
+application/vnd.ms-works wcm wdb wks wps
+application/vnd.ms-wpl wpl
+application/vnd.ms-xpsdocument xps
+application/vnd.msa-disk-image msa
+application/vnd.mseq mseq
+application/vnd.msign
+application/vnd.multiad.creator crtr
+application/vnd.multiad.creator.cif cif
+application/vnd.music-niff
+application/vnd.musician mus
+application/vnd.muvee.style msty
+application/vnd.mynfc taglet
+application/vnd.ncd.control
+application/vnd.ncd.reference
+application/vnd.nearst.inv+json
+application/vnd.nervana entity request bkm kcm
+application/vnd.netfpx
+# ntf: application/vnd.lotus-notes
+application/vnd.nitf nitf
+application/vnd.neurolanguage.nlu nlu
+application/vnd.nintendo.nitro.rom nds
+application/vnd.nintendo.snes.rom sfc smc
+application/vnd.noblenet-directory nnd
+application/vnd.noblenet-sealer nns
+application/vnd.noblenet-web nnw
+application/vnd.nokia.catalogs
+application/vnd.nokia.conml+wbxml
+application/vnd.nokia.conml+xml
+application/vnd.nokia.iptv.config+xml
+application/vnd.nokia.iSDS-radio-presets
+application/vnd.nokia.landmark+wbxml
+application/vnd.nokia.landmark+xml
+application/vnd.nokia.landmarkcollection+xml
+application/vnd.nokia.n-gage.ac+xml ac
+application/vnd.nokia.n-gage.data ngdat
+application/vnd.nokia.n-gage.symbian.install n-gage
+application/vnd.nokia.ncd
+application/vnd.nokia.pcd+wbxml
+application/vnd.nokia.pcd+xml
+application/vnd.nokia.radio-preset rpst
+application/vnd.nokia.radio-presets rpss
+application/vnd.novadigm.EDM edm
+application/vnd.novadigm.EDX edx
+application/vnd.novadigm.EXT ext
+application/vnd.ntt-local.content-share
+application/vnd.ntt-local.file-transfer
+application/vnd.ntt-local.ogw_remote-access
+application/vnd.ntt-local.sip-ta_remote
+application/vnd.ntt-local.sip-ta_tcp_stream
+application/vnd.oasis.opendocument.chart odc
+application/vnd.oasis.opendocument.chart-template otc
+application/vnd.oasis.opendocument.database odb
+application/vnd.oasis.opendocument.formula odf
+# otf: font/otf
+application/vnd.oasis.opendocument.formula-template
+application/vnd.oasis.opendocument.graphics odg
+application/vnd.oasis.opendocument.graphics-template otg
+application/vnd.oasis.opendocument.image odi
+application/vnd.oasis.opendocument.image-template oti
+application/vnd.oasis.opendocument.presentation odp
+application/vnd.oasis.opendocument.presentation-template otp
+application/vnd.oasis.opendocument.spreadsheet ods
+application/vnd.oasis.opendocument.spreadsheet-template ots
+application/vnd.oasis.opendocument.text odt
+application/vnd.oasis.opendocument.text-master odm
+application/vnd.oasis.opendocument.text-template ott
+application/vnd.oasis.opendocument.text-web oth
+application/vnd.obn
+application/vnd.ocf+cbor
+application/vnd.oftn.l10n+json
+application/vnd.oipf.contentaccessdownload+xml
+application/vnd.oipf.contentaccessstreaming+xml
+application/vnd.oipf.cspg-hexbinary
+application/vnd.oipf.dae.svg+xml
+application/vnd.oipf.dae.xhtml+xml
+application/vnd.oipf.mippvcontrolmessage+xml
+application/vnd.oipf.pae.gem
+application/vnd.oipf.spdiscovery+xml
+application/vnd.oipf.spdlist+xml
+application/vnd.oipf.ueprofile+xml
+application/vnd.olpc-sugar xo
+application/vnd.oma.bcast.associated-procedure-parameter+xml
+application/vnd.oma.bcast.drm-trigger+xml
+application/vnd.oma.bcast.imd+xml
+application/vnd.oma.bcast.ltkm
+application/vnd.oma.bcast.notification+xml
+application/vnd.oma.bcast.provisioningtrigger
+application/vnd.oma.bcast.sgboot
+application/vnd.oma.bcast.sgdd+xml
+application/vnd.oma.bcast.sgdu
+application/vnd.oma.bcast.simple-symbol-container
+application/vnd.oma.bcast.smartcard-trigger+xml
+application/vnd.oma.bcast.sprov+xml
+application/vnd.oma.bcast.stkm
+application/vnd.oma.cab-address-book+xml
+application/vnd.oma.cab-feature-handler+xml
+application/vnd.oma.cab-pcc+xml
+application/vnd.oma.cab-subs-invite+xml
+application/vnd.oma.cab-user-prefs+xml
+application/vnd.oma.dcd
+application/vnd.oma.dcdc
+application/vnd.oma.dd2+xml dd2
+application/vnd.oma.drm.risd+xml
+application/vnd.oma.group-usage-list+xml
+application/vnd.oma.lwm2m+json
+application/vnd.oma.lwm2m+tlv
+application/vnd.oma.pal+xml
+application/vnd.oma.poc.detailed-progress-report+xml
+application/vnd.oma.poc.final-report+xml
+application/vnd.oma.poc.groups+xml
+application/vnd.oma.poc.invocation-descriptor+xml
+application/vnd.oma.poc.optimized-progress-report+xml
+application/vnd.oma.push
+application/vnd.oma.scidm.messages+xml
+application/vnd.oma.xcap-directory+xml
+application/vnd.oma-scws-config
+application/vnd.oma-scws-http-request
+application/vnd.oma-scws-http-response
+application/vnd.omads-email+xml
+application/vnd.omads-file+xml
+application/vnd.omads-folder+xml
+application/vnd.omaloc-supl-init
+application/vnd.onepager tam
+application/vnd.onepagertamp tamp
+application/vnd.onepagertamx tamx
+application/vnd.onepagertat tat
+application/vnd.onepagertatp tatp
+application/vnd.onepagertatx tatx
+application/vnd.openblox.game+xml obgx
+application/vnd.openblox.game-binary obg
+application/vnd.openeye.oeb oeb
+application/vnd.openofficeorg.extension oxt
+application/vnd.openstreetmap.data+xml osm
+application/vnd.openxmlformats-officedocument.custom-properties+xml
+application/vnd.openxmlformats-officedocument.customXmlProperties+xml
+application/vnd.openxmlformats-officedocument.drawing+xml
+application/vnd.openxmlformats-officedocument.drawingml.chart+xml
+application/vnd.openxmlformats-officedocument.drawingml.chartshapes+xml
+application/vnd.openxmlformats-officedocument.drawingml.diagramColors+xml
+application/vnd.openxmlformats-officedocument.drawingml.diagramData+xml
+application/vnd.openxmlformats-officedocument.drawingml.diagramLayout+xml
+application/vnd.openxmlformats-officedocument.drawingml.diagramStyle+xml
+application/vnd.openxmlformats-officedocument.extended-properties+xml
+application/vnd.openxmlformats-officedocument.presentationml.commentAuthors+xml
+application/vnd.openxmlformats-officedocument.presentationml.comments+xml
+application/vnd.openxmlformats-officedocument.presentationml.handoutMaster+xml
+application/vnd.openxmlformats-officedocument.presentationml.notesMaster+xml
+application/vnd.openxmlformats-officedocument.presentationml.notesSlide+xml
+application/vnd.openxmlformats-officedocument.presentationml.presProps+xml
+application/vnd.openxmlformats-officedocument.presentationml.presentation pptx
+application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml
+application/vnd.openxmlformats-officedocument.presentationml.slide sldx
+application/vnd.openxmlformats-officedocument.presentationml.slide+xml
+application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml
+application/vnd.openxmlformats-officedocument.presentationml.slideMaster+xml
+application/vnd.openxmlformats-officedocument.presentationml.slideUpdateInfo+xml
+application/vnd.openxmlformats-officedocument.presentationml.slideshow ppsx
+application/vnd.openxmlformats-officedocument.presentationml.slideshow.main+xml
+application/vnd.openxmlformats-officedocument.presentationml.tableStyles+xml
+application/vnd.openxmlformats-officedocument.presentationml.tags+xml
+application/vnd.openxmlformats-officedocument.presentationml.template potx
+application/vnd.openxmlformats-officedocument.presentationml.template.main+xml
+application/vnd.openxmlformats-officedocument.presentationml.viewProps+xml
+application/vnd.openxmlformats-officedocument.spreadsheetml.calcChain+xml
+application/vnd.openxmlformats-officedocument.spreadsheetml.chartsheet+xml
+application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml
+application/vnd.openxmlformats-officedocument.spreadsheetml.connections+xml
+application/vnd.openxmlformats-officedocument.spreadsheetml.dialogsheet+xml
+application/vnd.openxmlformats-officedocument.spreadsheetml.externalLink+xml
+application/vnd.openxmlformats-officedocument.spreadsheetml.pivotCacheDefinition+xml
+application/vnd.openxmlformats-officedocument.spreadsheetml.pivotCacheRecords+xml
+application/vnd.openxmlformats-officedocument.spreadsheetml.pivotTable+xml
+application/vnd.openxmlformats-officedocument.spreadsheetml.queryTable+xml
+application/vnd.openxmlformats-officedocument.spreadsheetml.revisionHeaders+xml
+application/vnd.openxmlformats-officedocument.spreadsheetml.revisionLog+xml
+application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml
+application/vnd.openxmlformats-officedocument.spreadsheetml.sheet xlsx
+application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml
+application/vnd.openxmlformats-officedocument.spreadsheetml.sheetMetadata+xml
+application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml
+application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml
+application/vnd.openxmlformats-officedocument.spreadsheetml.tableSingleCells+xml
+application/vnd.openxmlformats-officedocument.spreadsheetml.template xltx
+application/vnd.openxmlformats-officedocument.spreadsheetml.template.main+xml
+application/vnd.openxmlformats-officedocument.spreadsheetml.userNames+xml
+application/vnd.openxmlformats-officedocument.spreadsheetml.volatileDependencies+xml
+application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml
+application/vnd.openxmlformats-officedocument.theme+xml
+application/vnd.openxmlformats-officedocument.themeOverride+xml
+application/vnd.openxmlformats-officedocument.vmlDrawing
+application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml
+application/vnd.openxmlformats-officedocument.wordprocessingml.document docx
+application/vnd.openxmlformats-officedocument.wordprocessingml.document.glossary+xml
+application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml
+application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml
+application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml
+application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml
+application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml
+application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml
+application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml
+application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml
+application/vnd.openxmlformats-officedocument.wordprocessingml.template dotx
+application/vnd.openxmlformats-officedocument.wordprocessingml.template.main+xml
+application/vnd.openxmlformats-officedocument.wordprocessingml.webSettings+xml
+application/vnd.openxmlformats-package.core-properties+xml
+application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml
+application/vnd.openxmlformats-package.relationships+xml
+application/vnd.oracle.resource+json
+application/vnd.orange.indata
+application/vnd.osa.netdeploy ndc
+application/vnd.osgeo.mapguide.package mgp
+# jar: application/x-java-archive
+application/vnd.osgi.bundle
+application/vnd.osgi.dp dp
+application/vnd.osgi.subsystem esa
+application/vnd.otps.ct-kip+xml
+application/vnd.oxli.countgraph oxlicg
+application/vnd.pagerduty+json
+application/vnd.palm prc pdb pqa oprc
+application/vnd.panoply plp
+application/vnd.paos+xml
+application/vnd.pawaafile paw
+application/vnd.pcos
+application/vnd.pg.format str
+application/vnd.pg.osasli ei6
+application/vnd.piaccess.application-license pil
+application/vnd.picsel efif
+application/vnd.pmi.widget wg
+application/vnd.poc.group-advertisement+xml
+application/vnd.pocketlearn plf
+application/vnd.powerbuilder6 pbd
+application/vnd.powerbuilder6-s
+application/vnd.powerbuilder7
+application/vnd.powerbuilder7-s
+application/vnd.powerbuilder75
+application/vnd.powerbuilder75-s
+application/vnd.preminet preminet
+application/vnd.previewsystems.box box vbox
+application/vnd.proteus.magazine mgz
+application/vnd.publishare-delta-tree qps
+# pti: image/prs.pti
+application/vnd.pvi.ptid1 ptid
+application/vnd.pwg-multiplexed
+application/vnd.pwg-xhtml-print+xml
+application/vnd.qualcomm.brew-app-res bar
+application/vnd.quarantainenet
+application/vnd.Quark.QuarkXPress qxd qxt qwd qwt qxl qxb
+application/vnd.quobject-quoxdocument quox quiz
+application/vnd.radisys.moml+xml
+application/vnd.radisys.msml-audit-conf+xml
+application/vnd.radisys.msml-audit-conn+xml
+application/vnd.radisys.msml-audit-dialog+xml
+application/vnd.radisys.msml-audit-stream+xml
+application/vnd.radisys.msml-audit+xml
+application/vnd.radisys.msml-conf+xml
+application/vnd.radisys.msml-dialog-base+xml
+application/vnd.radisys.msml-dialog-fax-detect+xml
+application/vnd.radisys.msml-dialog-fax-sendrecv+xml
+application/vnd.radisys.msml-dialog-group+xml
+application/vnd.radisys.msml-dialog-speech+xml
+application/vnd.radisys.msml-dialog-transform+xml
+application/vnd.radisys.msml-dialog+xml
+application/vnd.radisys.msml+xml
+application/vnd.rainstor.data tree
+application/vnd.rapid
+application/vnd.rar rar
+application/vnd.realvnc.bed bed
+application/vnd.recordare.musicxml mxl
+application/vnd.recordare.musicxml+xml
+application/vnd.RenLearn.rlprint
+application/vnd.rig.cryptonote cryptonote
+application/vnd.route66.link66+xml link66
+# gbr: application/rpki-ghostbusters
+application/vnd.rs-274x
+application/vnd.ruckus.download
+application/vnd.s3sms
+application/vnd.sailingtracker.track st
+application/vnd.sbm.cid
+application/vnd.sbm.mid2
+application/vnd.scribus scd sla slaz
+application/vnd.sealed.3df s3df
+application/vnd.sealed.csf scsf
+application/vnd.sealed.doc sdoc sdo s1w
+application/vnd.sealed.eml seml sem
+application/vnd.sealed.mht smht smh
+application/vnd.sealed.net
+# spp: application/scvp-vp-response
+application/vnd.sealed.ppt sppt s1p
+application/vnd.sealed.tiff stif
+application/vnd.sealed.xls sxls sxl s1e
+# stm: audio/x-stm
+application/vnd.sealedmedia.softseal.html stml s1h
+application/vnd.sealedmedia.softseal.pdf spdf spd s1a
+application/vnd.seemail see
+application/vnd.sema sema
+application/vnd.semd semd
+application/vnd.semf semf
+application/vnd.shana.informed.formdata ifm
+application/vnd.shana.informed.formtemplate itp
+application/vnd.shana.informed.interchange iif
+application/vnd.shana.informed.package ipk
+application/vnd.SimTech-MindMapper twd twds
+application/vnd.siren+json
+application/vnd.smaf mmf
+application/vnd.smart.notebook notebook
+application/vnd.smart.teacher teacher
+application/vnd.software602.filler.form+xml fo
+application/vnd.software602.filler.form-xml-zip zfo
+application/vnd.solent.sdkm+xml sdkm sdkd
+application/vnd.spotfire.dxp dxp
+application/vnd.spotfire.sfs sfs
+application/vnd.sss-cod
+application/vnd.sss-dtf
+application/vnd.sss-ntf
+application/vnd.stepmania.package smzip
+application/vnd.stepmania.stepchart sm
+application/vnd.street-stream
+application/vnd.sun.wadl+xml wadl
+application/vnd.sus-calendar sus susp
+application/vnd.svd
+application/vnd.swiftview-ics
+application/vnd.syncml+xml xsm
+application/vnd.syncml.dm+wbxml bdm
+application/vnd.syncml.dm+xml xdm
+application/vnd.syncml.dm.notification
+application/vnd.syncml.dmddf+wbxml
+application/vnd.syncml.dmddf+xml ddf
+application/vnd.syncml.dmtnds+wbxml
+application/vnd.syncml.dmtnds+xml
+application/vnd.syncml.ds.notification
+application/vnd.tableschema+json
+application/vnd.tao.intent-module-archive tao
+application/vnd.tcpdump.pcap pcap cap dmp
+application/vnd.theqvd qvd
+application/vnd.tmd.mediaflex.api+xml
+application/vnd.tml vfr viaframe
+application/vnd.tmobile-livetv tmo
+application/vnd.tri.onesource
+application/vnd.trid.tpt tpt
+application/vnd.triscape.mxs mxs
+application/vnd.trueapp tra
+application/vnd.truedoc
+# cab: application/vnd.ms-cab-compressed
+application/vnd.ubisoft.webplayer
+application/vnd.ufdl ufdl ufd frm
+application/vnd.uiq.theme utz
+application/vnd.umajin umj
+application/vnd.unity unityweb
+application/vnd.uoml+xml uoml uo
+application/vnd.uplanet.alert
+application/vnd.uplanet.alert-wbxml
+application/vnd.uplanet.bearer-choice
+application/vnd.uplanet.bearer-choice-wbxml
+application/vnd.uplanet.cacheop
+application/vnd.uplanet.cacheop-wbxml
+application/vnd.uplanet.channel
+application/vnd.uplanet.channel-wbxml
+application/vnd.uplanet.list
+application/vnd.uplanet.list-wbxml
+application/vnd.uplanet.listcmd
+application/vnd.uplanet.listcmd-wbxml
+application/vnd.uplanet.signal
+application/vnd.uri-map urim urimap
+application/vnd.valve.source.material vmt
+application/vnd.vcx vcx
+# sxi: application/vnd.sun.xml.impress
+application/vnd.vd-study mxi study-inter model-inter
+# mcd: application/vnd.mcd
+application/vnd.vectorworks vwx
+application/vnd.vel+json
+application/vnd.verimatrix.vcas
+application/vnd.vidsoft.vidconference vsc
+application/vnd.visio vsd vst vsw vss
+application/vnd.visionary vis
+# vsc: application/vnd.vidsoft.vidconference
+application/vnd.vividence.scriptfile
+application/vnd.vsf vsf
+application/vnd.wap.sic sic
+application/vnd.wap.slc slc
+application/vnd.wap.wbxml wbxml
+application/vnd.wap.wmlc wmlc
+application/vnd.wap.wmlscriptc wmlsc
+application/vnd.webturbo wtb
+application/vnd.wfa.p2p p2p
+application/vnd.wfa.wsc wsc
+application/vnd.windows.devicepairing
+application/vnd.wmc wmc
+application/vnd.wmf.bootstrap
+# nb: application/mathematica for now
+application/vnd.wolfram.mathematica
+application/vnd.wolfram.mathematica.package m
+application/vnd.wolfram.player nbp
+application/vnd.wordperfect wpd
+application/vnd.wqd wqd
+application/vnd.wrq-hp3000-labelled
+application/vnd.wt.stf stf
+application/vnd.wv.csp+xml
+application/vnd.wv.csp+wbxml wv
+application/vnd.wv.ssp+xml
+application/vnd.xacml+json
+application/vnd.xara xar
+application/vnd.xfdl xfdl xfd
+application/vnd.xfdl.webform
+application/vnd.xmi+xml
+application/vnd.xmpie.cpkg cpkg
+application/vnd.xmpie.dpkg dpkg
+# dpkg: application/vnd.xmpie.dpkg
+application/vnd.xmpie.plan
+application/vnd.xmpie.ppkg ppkg
+application/vnd.xmpie.xlim xlim
+application/vnd.yamaha.hv-dic hvd
+application/vnd.yamaha.hv-script hvs
+application/vnd.yamaha.hv-voice hvp
+application/vnd.yamaha.openscoreformat osf
+application/vnd.yamaha.openscoreformat.osfpvg+xml
+application/vnd.yamaha.remote-setup
+application/vnd.yamaha.smaf-audio saf
+application/vnd.yamaha.smaf-phrase spf
+application/vnd.yamaha.through-ngn
+application/vnd.yamaha.tunnel-udpencap
+application/vnd.yaoweme yme
+application/vnd.yellowriver-custom-menu cmp
+application/vnd.zul zir zirz
+application/vnd.zzazz.deck+xml zaz
+application/voicexml+xml vxml
+application/vq-rtcp-xr
+application/watcherinfo+xml wif
+application/whoispp-query
+application/whoispp-response
+application/widget wgt
+application/wita
+application/wordperfect5.1
+application/wsdl+xml wsdl
+application/wspolicy+xml wspolicy
+# yes, this *is* IANA registered despite of x-
+application/x-www-form-urlencoded
+application/x400-bp
+application/xacml+xml
+application/xcap-att+xml xav
+application/xcap-caps+xml xca
+application/xcap-diff+xml xdf
+application/xcap-el+xml xel
+application/xcap-error+xml xer
+application/xcap-ns+xml xns
+application/xcon-conference-info-diff+xml
+application/xcon-conference-info+xml
+application/xenc+xml
+application/xhtml+xml xhtml xhtm xht
+# xml, xsd, rng: text/xml
+application/xml
+# mod: audio/x-mod
+application/xml-dtd dtd
+# ent: text/xml-external-parsed-entity
+application/xml-external-parsed-entity
+application/xml-patch+xml
+application/xmpp+xml
+application/xop+xml xop
+application/xslt+xml xsl xslt
+application/xv+xml mxml xhvml xvml xvm
+application/yang yang
+application/yang-data+json
+application/yang-data+xml
+application/yang-patch+json
+application/yang-patch+xml
+application/yin+xml yin
+application/zip zip
+application/zlib
+audio/1d-interleaved-parityfec
+audio/32kadpcm 726
+# 3gp, 3gpp: video/3gpp
+audio/3gpp
+# 3g2, 3gpp2: video/3gpp2
+audio/3gpp2
+audio/ac3 ac3
+audio/AMR amr
+audio/AMR-WB awb
+audio/amr-wb+
+audio/aptx
+audio/asc acn
+# aa3, omg: audio/ATRAC3
+audio/ATRAC-ADVANCED-LOSSLESS aal
+# aa3, omg: audio/ATRAC3
+audio/ATRAC-X atx
+audio/ATRAC3 at3 aa3 omg
+audio/basic au snd
+audio/BV16
+audio/BV32
+audio/clearmode
+audio/CN
+audio/DAT12
+audio/dls dls
+audio/dsr-es201108
+audio/dsr-es202050
+audio/dsr-es202211
+audio/dsr-es202212
+audio/DV
+audio/DVI4
+audio/eac3
+audio/encaprtp
+audio/EVRC evc
+# qcp: audio/qcelp
+audio/EVRC-QCP
+audio/EVRC0
+audio/EVRC1
+audio/EVRCB evb
+audio/EVRCB0
+audio/EVRCB1
+audio/EVRCNW enw
+audio/EVRCNW0
+audio/EVRCNW1
+audio/EVRCWB evw
+audio/EVRCWB0
+audio/EVRCWB1
+audio/EVS
+audio/example
+audio/fwdred
+audio/G711-0
+audio/G719
+audio/G722
+audio/G7221
+audio/G723
+audio/G726-16
+audio/G726-24
+audio/G726-32
+audio/G726-40
+audio/G728
+audio/G729
+audio/G7291
+audio/G729D
+audio/G729E
+audio/GSM
+audio/GSM-EFR
+audio/GSM-HR-08
+audio/iLBC lbc
+audio/ip-mr_v2.5
+# wav: audio/x-wav
+audio/L16 l16
+audio/L20
+audio/L24
+audio/L8
+audio/LPC
+audio/MELP
+audio/MELP600
+audio/MELP1200
+audio/MELP2400
+audio/mobile-xmf mxmf
+# mp4, mpg4: video/mp4, see RFC 4337
+audio/mp4 m4a
+audio/MP4A-LATM
+audio/MPA
+audio/mpa-robust
+audio/mpeg mp3 mpga mp1 mp2
+audio/mpeg4-generic
+audio/ogg oga ogg opus spx
+audio/opus
+audio/parityfec
+audio/PCMA
+audio/PCMA-WB
+audio/PCMU
+audio/PCMU-WB
+audio/prs.sid sid psid
+audio/qcelp qcp
+audio/raptorfec
+audio/RED
+audio/rtp-enc-aescm128
+audio/rtp-midi
+audio/rtploopback
+audio/rtx
+audio/SMV smv
+# qcp: audio/qcelp, see RFC 3625
+audio/SMV-QCP
+audio/SMV0
+# mid: audio/midi
+audio/sp-midi
+audio/speex
+audio/t140c
+audio/t38
+audio/telephone-event
+audio/tone
+audio/UEMCLIP
+audio/ulpfec
+audio/VDVI
+audio/VMR-WB
+audio/vnd.3gpp.iufp
+audio/vnd.4SB
+audio/vnd.audikoz koz
+audio/vnd.CELP
+audio/vnd.cisco.nse
+audio/vnd.cmles.radio-events
+audio/vnd.cns.anp1
+audio/vnd.cns.inf1
+audio/vnd.dece.audio uva uvva
+audio/vnd.digital-winds eol
+audio/vnd.dlna.adts
+audio/vnd.dolby.heaac.1
+audio/vnd.dolby.heaac.2
+audio/vnd.dolby.mlp mlp
+audio/vnd.dolby.mps
+audio/vnd.dolby.pl2
+audio/vnd.dolby.pl2x
+audio/vnd.dolby.pl2z
+audio/vnd.dolby.pulse.1
+audio/vnd.dra
+# wav: audio/x-wav, cpt: application/mac-compactpro
+audio/vnd.dts dts
+audio/vnd.dts.hd dtshd
+# dvb: video/vnd.dvb.file
+audio/vnd.dvb.file
+audio/vnd.everad.plj plj
+# rm: audio/x-pn-realaudio
+audio/vnd.hns.audio
+audio/vnd.lucent.voice lvp
+audio/vnd.ms-playready.media.pya pya
+# mxmf: audio/mobile-xmf
+audio/vnd.nokia.mobile-xmf
+audio/vnd.nortel.vbk vbk
+audio/vnd.nuera.ecelp4800 ecelp4800
+audio/vnd.nuera.ecelp7470 ecelp7470
+audio/vnd.nuera.ecelp9600 ecelp9600
+audio/vnd.octel.sbc
+# audio/vnd.qcelp deprecated in favour of audio/qcelp
+audio/vnd.rhetorex.32kadpcm
+audio/vnd.rip rip
+audio/vnd.sealedmedia.softseal.mpeg smp3 smp s1m
+audio/vnd.vmx.cvsd
+audio/vorbis
+audio/vorbis-config
+font/collection ttc
+font/otf otf
+font/sfnt
+font/ttf ttf
+font/woff woff
+font/woff2 woff2
+image/bmp bmp dib
+image/cgm cgm
+image/dicom-rle drle
+image/emf emf
+image/example
+image/fits fits fit fts
+image/g3fax
+image/gif gif
+image/ief ief
+image/jls jls
+image/jp2 jp2 jpg2
+image/jpeg jpg jpeg jpe jfif
+image/jpm jpm jpgm
+image/jpx jpx jpf
+image/ktx ktx
+image/naplps
+image/png png
+image/prs.btif btif btf
+image/prs.pti pti
+image/pwg-raster
+image/svg+xml svg svgz
+image/t38 t38
+image/tiff tiff tif
+image/tiff-fx tfx
+image/vnd.adobe.photoshop psd
+image/vnd.airzip.accelerator.azv azv
+image/vnd.cns.inf2
+image/vnd.dece.graphic uvi uvvi uvg uvvg
+image/vnd.djvu djvu djv
+# sub: text/vnd.dvb.subtitle
+image/vnd.dvb.subtitle
+image/vnd.dwg dwg
+image/vnd.dxf dxf
+image/vnd.fastbidsheet fbs
+image/vnd.fpx fpx
+image/vnd.fst fst
+image/vnd.fujixerox.edmics-mmr mmr
+image/vnd.fujixerox.edmics-rlc rlc
+image/vnd.globalgraphics.pgb pgb
+image/vnd.microsoft.icon ico
+image/vnd.mix
+image/vnd.mozilla.apng apng
+image/vnd.ms-modi mdi
+image/vnd.net-fpx
+image/vnd.radiance hdr rgbe xyze
+image/vnd.sealed.png spng spn s1n
+image/vnd.sealedmedia.softseal.gif sgif sgi s1g
+image/vnd.sealedmedia.softseal.jpg sjpg sjp s1j
+image/vnd.svf
+image/vnd.tencent.tap tap
+image/vnd.valve.source.texture vtf
+image/vnd.wap.wbmp wbmp
+image/vnd.xiff xif
+image/vnd.zbrush.pcx pcx
+image/wmf wmf
+message/CPIM
+message/delivery-status
+message/disposition-notification
+message/example
+message/external-body
+message/feedback-report
+message/global u8msg
+message/global-delivery-status u8dsn
+message/global-disposition-notification u8mdn
+message/global-headers u8hdr
+message/http
+# cl: application/simple-filter+xml
+message/imdn+xml
+# message/news obsoleted by message/rfc822
+message/partial
+message/rfc822 eml mail art
+message/s-http
+message/sip
+message/sipfrag
+message/tracking-status
+message/vnd.si.simp
+# wsc: application/vnd.wfa.wsc
+message/vnd.wfa.wsc
+model/example
+model/gltf+json gltf
+model/iges igs iges
+model/mesh msh mesh silo
+model/vnd.collada+xml dae
+model/vnd.dwf dwf
+# 3dml, 3dm: text/vnd.in3d.3dml
+model/vnd.flatland.3dml
+model/vnd.gdl gdl gsm win dor lmp rsm msm ism
+model/vnd.gs-gdl
+model/vnd.gtw gtw
+model/vnd.moml+xml moml
+model/vnd.mts mts
+model/vnd.opengex ogex
+model/vnd.parasolid.transmit.binary x_b xmt_bin
+model/vnd.parasolid.transmit.text x_t xmt_txt
+model/vnd.rosette.annotated-data-model
+model/vnd.valve.source.compiled-map bsp
+model/vnd.vtu vtu
+model/vrml wrl vrml
+# x3db: model/x3d+xml
+model/x3d+fastinfoset
+# x3d: application/vnd.hzn-3d-crossword
+model/x3d+xml x3db
+model/x3d-vrml x3dv x3dvz
+multipart/alternative
+multipart/appledouble
+multipart/byteranges
+multipart/digest
+multipart/encrypted
+multipart/form-data
+multipart/header-set
+multipart/mixed
+multipart/parallel
+multipart/related
+multipart/report
+multipart/signed
+multipart/vnd.bint.med-plus bmed
+multipart/voice-message vpm
+multipart/x-mixed-replace
+text/1d-interleaved-parityfec
+text/cache-manifest appcache manifest
+text/calendar ics ifb
+text/css css
+text/csv csv
+text/csv-schema csvs
+text/directory
+text/dns soa zone
+text/encaprtp
+# text/ecmascript obsoleted by application/ecmascript
+text/enriched
+text/example
+text/fwdred
+text/grammar-ref-list
+text/html html htm
+# text/javascript obsoleted by application/javascript
+text/jcr-cnd cnd
+text/markdown markdown md
+text/mizar miz
+text/n3 n3
+text/parameters
+text/parityfec
+text/plain txt asc text pm el c h cc hh cxx hxx f90 conf log
+text/provenance-notation provn
+text/prs.fallenstein.rst rst
+text/prs.lines.tag tag dsc
+text/prs.prop.logic
+text/raptorfec
+text/RED
+text/rfc822-headers
+text/richtext rtx
+# rtf: application/rtf
+text/rtf
+text/rtp-enc-aescm128
+text/rtploopback
+text/rtx
+text/sgml sgml sgm
+text/strings
+text/t140
+text/tab-separated-values tsv
+text/troff t tr roff
+text/turtle ttl
+text/ulpfec
+text/uri-list uris uri
+text/vcard vcf vcard
+text/vnd.a a
+text/vnd.abc abc
+text/vnd.ascii-art ascii
+# curl: application/vnd.curl
+text/vnd.curl
+text/vnd.debian.copyright copyright
+text/vnd.DMClientScript dms
+text/vnd.dvb.subtitle sub
+text/vnd.esmertec.theme-descriptor jtd
+text/vnd.fly fly
+text/vnd.fmi.flexstor flx
+text/vnd.graphviz gv dot
+text/vnd.in3d.3dml 3dml 3dm
+text/vnd.in3d.spot spot spo
+text/vnd.IPTC.NewsML
+text/vnd.IPTC.NITF
+text/vnd.latex-z
+text/vnd.motorola.reflex
+text/vnd.ms-mediapackage mpf
+text/vnd.net2phone.commcenter.command ccc
+text/vnd.radisys.msml-basic-layout
+text/vnd.si.uricatalogue uric
+text/vnd.sun.j2me.app-descriptor jad
+text/vnd.trolltech.linguist ts
+text/vnd.wap.si si
+text/vnd.wap.sl sl
+text/vnd.wap.wml wml
+text/vnd.wap.wmlscript wmls
+text/xml xml xsd rng
+text/xml-external-parsed-entity ent
+video/1d-interleaved-parityfec
+video/3gpp 3gp 3gpp
+video/3gpp2 3g2 3gpp2
+video/3gpp-tt
+video/BMPEG
+video/BT656
+video/CelB
+video/DV
+video/encaprtp
+video/example
+video/H261
+video/H263
+video/H263-1998
+video/H263-2000
+video/H264
+video/H264-RCDO
+video/H264-SVC
+video/H265
+video/iso.segment m4s
+video/JPEG
+video/jpeg2000
+video/mj2 mj2 mjp2
+video/MP1S
+video/MP2P
+video/MP2T
+video/mp4 mp4 mpg4 m4v
+video/MP4V-ES
+video/mpeg mpeg mpg mpe m1v m2v
+video/mpeg4-generic
+video/MPV
+video/nv
+video/ogg ogv
+video/parityfec
+video/pointer
+video/quicktime mov qt
+video/raptorfec
+video/raw
+video/rtp-enc-aescm128
+video/rtploopback
+video/rtx
+video/SMPTE292M
+video/ulpfec
+video/vc1
+video/vnd.CCTV
+video/vnd.dece.hd uvh uvvh
+video/vnd.dece.mobile uvm uvvm
+video/vnd.dece.mp4 uvu uvvu
+video/vnd.dece.pd uvp uvvp
+video/vnd.dece.sd uvs uvvs
+video/vnd.dece.video uvv uvvv
+video/vnd.directv.mpeg
+video/vnd.directv.mpeg-tts
+video/vnd.dlna.mpeg-tts
+video/vnd.dvb.file dvb
+video/vnd.fvt fvt
+# rm: audio/x-pn-realaudio
+video/vnd.hns.video
+video/vnd.iptvforum.1dparityfec-1010
+video/vnd.iptvforum.1dparityfec-2005
+video/vnd.iptvforum.2dparityfec-1010
+video/vnd.iptvforum.2dparityfec-2005
+video/vnd.iptvforum.ttsavc
+video/vnd.iptvforum.ttsmpeg2
+video/vnd.motorola.video
+video/vnd.motorola.videop
+video/vnd.mpegurl mxu m4u
+video/vnd.ms-playready.media.pyv pyv
+video/vnd.nokia.interleaved-multimedia nim
+video/vnd.nokia.videovoip
+# mp4: video/mp4
+video/vnd.objectvideo
+video/vnd.radgamettools.bink bik bk2
+video/vnd.radgamettools.smacker smk
+video/vnd.sealed.mpeg1 smpg s11
+# smpg: video/vnd.sealed.mpeg1
+video/vnd.sealed.mpeg4 s14
+video/vnd.sealed.swf sswf ssw
+video/vnd.sealedmedia.softseal.mov smov smo s1q
+# uvu, uvvu: video/vnd.dece.mp4
+video/vnd.uvvu.mp4
+video/vnd.vivo viv
+video/VP8
+
+# Non-IANA types
+
+application/mac-compactpro cpt
+application/metalink+xml metalink
+application/owl+xml owx
+application/rss+xml rss
+application/vnd.android.package-archive apk
+application/vnd.oma.dd+xml dd
+application/vnd.oma.drm.content dcf
+# odf: application/vnd.oasis.opendocument.formula
+application/vnd.oma.drm.dcf o4a o4v
+application/vnd.oma.drm.message dm
+application/vnd.oma.drm.rights+wbxml drc
+application/vnd.oma.drm.rights+xml dr
+application/vnd.sun.xml.calc sxc
+application/vnd.sun.xml.calc.template stc
+application/vnd.sun.xml.draw sxd
+application/vnd.sun.xml.draw.template std
+application/vnd.sun.xml.impress sxi
+application/vnd.sun.xml.impress.template sti
+application/vnd.sun.xml.math sxm
+application/vnd.sun.xml.writer sxw
+application/vnd.sun.xml.writer.global sxg
+application/vnd.sun.xml.writer.template stw
+application/vnd.symbian.install sis
+application/vnd.wap.mms-message mms
+application/x-annodex anx
+application/x-bcpio bcpio
+application/x-bittorrent torrent
+application/x-bzip2 bz2
+application/x-cdlink vcd
+application/x-chrome-extension crx
+application/x-cpio cpio
+application/x-csh csh
+application/x-director dcr dir dxr
+application/x-dvi dvi
+application/x-futuresplash spl
+application/x-gtar gtar
+application/x-hdf hdf
+application/x-java-archive jar
+application/x-java-jnlp-file jnlp
+application/x-java-pack200 pack
+application/x-killustrator kil
+application/x-latex latex
+application/x-netcdf nc cdf
+application/x-perl pl
+application/x-rpm rpm
+application/x-sh sh
+application/x-shar shar
+application/x-stuffit sit
+application/x-sv4cpio sv4cpio
+application/x-sv4crc sv4crc
+application/x-tar tar
+application/x-tcl tcl
+application/x-tex tex
+application/x-texinfo texinfo texi
+application/x-troff-man man 1 2 3 4 5 6 7 8
+application/x-troff-me me
+application/x-troff-ms ms
+application/x-ustar ustar
+application/x-wais-source src
+application/x-xpinstall xpi
+application/x-xspf+xml xspf
+application/x-xz xz
+audio/midi mid midi kar
+audio/x-aiff aif aiff aifc
+audio/x-annodex axa
+audio/x-flac flac
+audio/x-matroska mka
+audio/x-mod mod ult uni m15 mtm 669 med
+audio/x-mpegurl m3u
+audio/x-ms-wax wax
+audio/x-ms-wma wma
+audio/x-pn-realaudio ram rm
+audio/x-realaudio ra
+audio/x-s3m s3m
+audio/x-stm stm
+audio/x-wav wav
+chemical/x-xyz xyz
+image/webp webp
+image/x-cmu-raster ras
+image/x-portable-anymap pnm
+image/x-portable-bitmap pbm
+image/x-portable-graymap pgm
+image/x-portable-pixmap ppm
+image/x-rgb rgb
+image/x-targa tga
+image/x-xbitmap xbm
+image/x-xpixmap xpm
+image/x-xwindowdump xwd
+text/html-sandboxed sandboxed
+text/x-pod pod
+text/x-setext etx
+video/webm webm
+video/x-annodex axv
+video/x-flv flv
+video/x-javafx fxm
+video/x-matroska mkv
+video/x-matroska-3d mk3d
+video/x-ms-asf asx
+video/x-ms-wm wm
+video/x-ms-wmv wmv
+video/x-ms-wmx wmx
+video/x-ms-wvx wvx
+video/x-msvideo avi
+video/x-sgi-movie movie
+x-conference/x-cooltalk ice
+x-epoc/x-sisx-app sisx
diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/swarm/swarm-smoke/feed_upload_and_sync.go b/vendor/github.com/ethereum/go-ethereum/cmd/swarm/swarm-smoke/feed_upload_and_sync.go
new file mode 100644
index 00000000..6b3fed0c
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/cmd/swarm/swarm-smoke/feed_upload_and_sync.go
@@ -0,0 +1,291 @@
+package main
+
+import (
+ "bytes"
+ "crypto/md5"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "os"
+ "os/exec"
+ "strings"
+ "sync"
+ "time"
+
+ "github.com/ethereum/go-ethereum/common/hexutil"
+ "github.com/ethereum/go-ethereum/crypto"
+ "github.com/ethereum/go-ethereum/log"
+ "github.com/ethereum/go-ethereum/metrics"
+ "github.com/ethereum/go-ethereum/swarm/storage/feed"
+ "github.com/ethereum/go-ethereum/swarm/testutil"
+ "github.com/pborman/uuid"
+ cli "gopkg.in/urfave/cli.v1"
+)
+
+const (
+ feedRandomDataLength = 8
+)
+
+func feedUploadAndSyncCmd(ctx *cli.Context, tuid string) error {
+ errc := make(chan error)
+
+ go func() {
+ errc <- feedUploadAndSync(ctx, tuid)
+ }()
+
+ select {
+ case err := <-errc:
+ if err != nil {
+ metrics.GetOrRegisterCounter(fmt.Sprintf("%s.fail", commandName), nil).Inc(1)
+ }
+ return err
+ case <-time.After(time.Duration(timeout) * time.Second):
+ metrics.GetOrRegisterCounter(fmt.Sprintf("%s.timeout", commandName), nil).Inc(1)
+
+ return fmt.Errorf("timeout after %v sec", timeout)
+ }
+}
+
+func feedUploadAndSync(c *cli.Context, tuid string) error {
+ log.Info("generating and uploading feeds to " + httpEndpoint(hosts[0]) + " and syncing")
+
+ // create a random private key to sign updates with and derive the address
+ pkFile, err := ioutil.TempFile("", "swarm-feed-smoke-test")
+ if err != nil {
+ return err
+ }
+ defer pkFile.Close()
+ defer os.Remove(pkFile.Name())
+
+ privkeyHex := "0000000000000000000000000000000000000000000000000000000000001976"
+ privKey, err := crypto.HexToECDSA(privkeyHex)
+ if err != nil {
+ return err
+ }
+ user := crypto.PubkeyToAddress(privKey.PublicKey)
+ userHex := hexutil.Encode(user.Bytes())
+
+ // save the private key to a file
+ _, err = io.WriteString(pkFile, privkeyHex)
+ if err != nil {
+ return err
+ }
+
+ // keep hex strings for topic and subtopic
+ var topicHex string
+ var subTopicHex string
+
+ // and create combination hex topics for bzz-feed retrieval
+ // xor'ed with topic (zero-value topic if no topic)
+ var subTopicOnlyHex string
+ var mergedSubTopicHex string
+
+ // generate random topic and subtopic and put a hex on them
+ topicBytes, err := generateRandomData(feed.TopicLength)
+ topicHex = hexutil.Encode(topicBytes)
+ subTopicBytes, err := generateRandomData(8)
+ subTopicHex = hexutil.Encode(subTopicBytes)
+ if err != nil {
+ return err
+ }
+ mergedSubTopic, err := feed.NewTopic(subTopicHex, topicBytes)
+ if err != nil {
+ return err
+ }
+ mergedSubTopicHex = hexutil.Encode(mergedSubTopic[:])
+ subTopicOnlyBytes, err := feed.NewTopic(subTopicHex, nil)
+ if err != nil {
+ return err
+ }
+ subTopicOnlyHex = hexutil.Encode(subTopicOnlyBytes[:])
+
+ // create feed manifest, topic only
+ var out bytes.Buffer
+ cmd := exec.Command("swarm", "--bzzapi", httpEndpoint(hosts[0]), "feed", "create", "--topic", topicHex, "--user", userHex)
+ cmd.Stdout = &out
+ log.Debug("create feed manifest topic cmd", "cmd", cmd)
+ err = cmd.Run()
+ if err != nil {
+ return err
+ }
+ manifestWithTopic := strings.TrimRight(out.String(), string([]byte{0x0a}))
+ if len(manifestWithTopic) != 64 {
+ return fmt.Errorf("unknown feed create manifest hash format (topic): (%d) %s", len(out.String()), manifestWithTopic)
+ }
+ log.Debug("create topic feed", "manifest", manifestWithTopic)
+ out.Reset()
+
+ // create feed manifest, subtopic only
+ cmd = exec.Command("swarm", "--bzzapi", httpEndpoint(hosts[0]), "feed", "create", "--name", subTopicHex, "--user", userHex)
+ cmd.Stdout = &out
+ log.Debug("create feed manifest subtopic cmd", "cmd", cmd)
+ err = cmd.Run()
+ if err != nil {
+ return err
+ }
+ manifestWithSubTopic := strings.TrimRight(out.String(), string([]byte{0x0a}))
+ if len(manifestWithSubTopic) != 64 {
+ return fmt.Errorf("unknown feed create manifest hash format (subtopic): (%d) %s", len(out.String()), manifestWithSubTopic)
+ }
+ log.Debug("create subtopic feed", "manifest", manifestWithTopic)
+ out.Reset()
+
+ // create feed manifest, merged topic
+ cmd = exec.Command("swarm", "--bzzapi", httpEndpoint(hosts[0]), "feed", "create", "--topic", topicHex, "--name", subTopicHex, "--user", userHex)
+ cmd.Stdout = &out
+ log.Debug("create feed manifest mergetopic cmd", "cmd", cmd)
+ err = cmd.Run()
+ if err != nil {
+ log.Error(err.Error())
+ return err
+ }
+ manifestWithMergedTopic := strings.TrimRight(out.String(), string([]byte{0x0a}))
+ if len(manifestWithMergedTopic) != 64 {
+ return fmt.Errorf("unknown feed create manifest hash format (mergedtopic): (%d) %s", len(out.String()), manifestWithMergedTopic)
+ }
+ log.Debug("create mergedtopic feed", "manifest", manifestWithMergedTopic)
+ out.Reset()
+
+ // create test data
+ data, err := generateRandomData(feedRandomDataLength)
+ if err != nil {
+ return err
+ }
+ h := md5.New()
+ h.Write(data)
+ dataHash := h.Sum(nil)
+ dataHex := hexutil.Encode(data)
+
+ // update with topic
+ cmd = exec.Command("swarm", "--bzzaccount", pkFile.Name(), "--bzzapi", httpEndpoint(hosts[0]), "feed", "update", "--topic", topicHex, dataHex)
+ cmd.Stdout = &out
+ log.Debug("update feed manifest topic cmd", "cmd", cmd)
+ err = cmd.Run()
+ if err != nil {
+ return err
+ }
+ log.Debug("feed update topic", "out", out)
+ out.Reset()
+
+ // update with subtopic
+ cmd = exec.Command("swarm", "--bzzaccount", pkFile.Name(), "--bzzapi", httpEndpoint(hosts[0]), "feed", "update", "--name", subTopicHex, dataHex)
+ cmd.Stdout = &out
+ log.Debug("update feed manifest subtopic cmd", "cmd", cmd)
+ err = cmd.Run()
+ if err != nil {
+ return err
+ }
+ log.Debug("feed update subtopic", "out", out)
+ out.Reset()
+
+ // update with merged topic
+ cmd = exec.Command("swarm", "--bzzaccount", pkFile.Name(), "--bzzapi", httpEndpoint(hosts[0]), "feed", "update", "--topic", topicHex, "--name", subTopicHex, dataHex)
+ cmd.Stdout = &out
+ log.Debug("update feed manifest merged topic cmd", "cmd", cmd)
+ err = cmd.Run()
+ if err != nil {
+ return err
+ }
+ log.Debug("feed update mergedtopic", "out", out)
+ out.Reset()
+
+ time.Sleep(3 * time.Second)
+
+ // retrieve the data
+ wg := sync.WaitGroup{}
+ for _, host := range hosts {
+ // raw retrieve, topic only
+ for _, hex := range []string{topicHex, subTopicOnlyHex, mergedSubTopicHex} {
+ wg.Add(1)
+ ruid := uuid.New()[:8]
+ go func(hex string, endpoint string, ruid string) {
+ for {
+ err := fetchFeed(hex, userHex, httpEndpoint(host), dataHash, ruid)
+ if err != nil {
+ continue
+ }
+
+ wg.Done()
+ return
+ }
+ }(hex, httpEndpoint(host), ruid)
+ }
+ }
+ wg.Wait()
+ log.Info("all endpoints synced random data successfully")
+
+ // upload test file
+ log.Info("feed uploading to "+httpEndpoint(hosts[0])+" and syncing", "seed", seed)
+
+ randomBytes := testutil.RandomBytes(seed, filesize*1000)
+
+ hash, err := upload(randomBytes, httpEndpoint(hosts[0]))
+ if err != nil {
+ return err
+ }
+ hashBytes, err := hexutil.Decode("0x" + hash)
+ if err != nil {
+ return err
+ }
+ multihashHex := hexutil.Encode(hashBytes)
+ fileHash := h.Sum(nil)
+
+ log.Info("uploaded successfully", "hash", hash, "digest", fmt.Sprintf("%x", fileHash))
+
+ // update file with topic
+ cmd = exec.Command("swarm", "--bzzaccount", pkFile.Name(), "--bzzapi", httpEndpoint(hosts[0]), "feed", "update", "--topic", topicHex, multihashHex)
+ cmd.Stdout = &out
+ err = cmd.Run()
+ if err != nil {
+ return err
+ }
+ log.Debug("feed update topic", "out", out)
+ out.Reset()
+
+ // update file with subtopic
+ cmd = exec.Command("swarm", "--bzzaccount", pkFile.Name(), "--bzzapi", httpEndpoint(hosts[0]), "feed", "update", "--name", subTopicHex, multihashHex)
+ cmd.Stdout = &out
+ err = cmd.Run()
+ if err != nil {
+ return err
+ }
+ log.Debug("feed update subtopic", "out", out)
+ out.Reset()
+
+ // update file with merged topic
+ cmd = exec.Command("swarm", "--bzzaccount", pkFile.Name(), "--bzzapi", httpEndpoint(hosts[0]), "feed", "update", "--topic", topicHex, "--name", subTopicHex, multihashHex)
+ cmd.Stdout = &out
+ err = cmd.Run()
+ if err != nil {
+ return err
+ }
+ log.Debug("feed update mergedtopic", "out", out)
+ out.Reset()
+
+ time.Sleep(3 * time.Second)
+
+ for _, host := range hosts {
+
+ // manifest retrieve, topic only
+ for _, url := range []string{manifestWithTopic, manifestWithSubTopic, manifestWithMergedTopic} {
+ wg.Add(1)
+ ruid := uuid.New()[:8]
+ go func(url string, endpoint string, ruid string) {
+ for {
+ err := fetch(url, endpoint, fileHash, ruid, "")
+ if err != nil {
+ continue
+ }
+
+ wg.Done()
+ return
+ }
+ }(url, httpEndpoint(host), ruid)
+ }
+
+ }
+ wg.Wait()
+ log.Info("all endpoints synced random file successfully")
+
+ return nil
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/swarm/swarm-smoke/main.go b/vendor/github.com/ethereum/go-ethereum/cmd/swarm/swarm-smoke/main.go
new file mode 100644
index 00000000..860fbcc1
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/cmd/swarm/swarm-smoke/main.go
@@ -0,0 +1,197 @@
+// Copyright 2018 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// go-ethereum is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with go-ethereum. If not, see .
+
+package main
+
+import (
+ "fmt"
+ "os"
+ "sort"
+
+ "github.com/ethereum/go-ethereum/cmd/utils"
+ gethmetrics "github.com/ethereum/go-ethereum/metrics"
+ "github.com/ethereum/go-ethereum/metrics/influxdb"
+ swarmmetrics "github.com/ethereum/go-ethereum/swarm/metrics"
+ "github.com/ethereum/go-ethereum/swarm/tracing"
+
+ "github.com/ethereum/go-ethereum/log"
+
+ cli "gopkg.in/urfave/cli.v1"
+)
+
+var (
+ gitCommit string // Git SHA1 commit hash of the release (set via linker flags)
+)
+
+var (
+ allhosts string
+ hosts []string
+ filesize int
+ inputSeed int
+ syncDelay int
+ httpPort int
+ wsPort int
+ verbosity int
+ timeout int
+ single bool
+ trackTimeout int
+)
+
+func main() {
+
+ app := cli.NewApp()
+ app.Name = "smoke-test"
+ app.Usage = ""
+
+ app.Flags = []cli.Flag{
+ cli.StringFlag{
+ Name: "hosts",
+ Value: "",
+ Usage: "comma-separated list of swarm hosts",
+ Destination: &allhosts,
+ },
+ cli.IntFlag{
+ Name: "http-port",
+ Value: 80,
+ Usage: "http port",
+ Destination: &httpPort,
+ },
+ cli.IntFlag{
+ Name: "ws-port",
+ Value: 8546,
+ Usage: "ws port",
+ Destination: &wsPort,
+ },
+ cli.IntFlag{
+ Name: "seed",
+ Value: 0,
+ Usage: "input seed in case we need deterministic upload",
+ Destination: &inputSeed,
+ },
+ cli.IntFlag{
+ Name: "filesize",
+ Value: 1024,
+ Usage: "file size for generated random file in KB",
+ Destination: &filesize,
+ },
+ cli.IntFlag{
+ Name: "sync-delay",
+ Value: 5,
+ Usage: "duration of delay in seconds to wait for content to be synced",
+ Destination: &syncDelay,
+ },
+ cli.IntFlag{
+ Name: "verbosity",
+ Value: 1,
+ Usage: "verbosity",
+ Destination: &verbosity,
+ },
+ cli.IntFlag{
+ Name: "timeout",
+ Value: 120,
+ Usage: "timeout in seconds after which kill the process",
+ Destination: &timeout,
+ },
+ cli.BoolFlag{
+ Name: "single",
+ Usage: "whether to fetch content from a single node or from all nodes",
+ Destination: &single,
+ },
+ cli.IntFlag{
+ Name: "track-timeout",
+ Value: 5,
+ Usage: "timeout in seconds to wait for GetAllReferences to return",
+ Destination: &trackTimeout,
+ },
+ }
+
+ app.Flags = append(app.Flags, []cli.Flag{
+ utils.MetricsEnabledFlag,
+ swarmmetrics.MetricsInfluxDBEndpointFlag,
+ swarmmetrics.MetricsInfluxDBDatabaseFlag,
+ swarmmetrics.MetricsInfluxDBUsernameFlag,
+ swarmmetrics.MetricsInfluxDBPasswordFlag,
+ swarmmetrics.MetricsInfluxDBTagsFlag,
+ }...)
+
+ app.Flags = append(app.Flags, tracing.Flags...)
+
+ app.Commands = []cli.Command{
+ {
+ Name: "upload_and_sync",
+ Aliases: []string{"c"},
+ Usage: "upload and sync",
+ Action: wrapCliCommand("upload-and-sync", uploadAndSyncCmd),
+ },
+ {
+ Name: "feed_sync",
+ Aliases: []string{"f"},
+ Usage: "feed update generate, upload and sync",
+ Action: wrapCliCommand("feed-and-sync", feedUploadAndSyncCmd),
+ },
+ {
+ Name: "upload_speed",
+ Aliases: []string{"u"},
+ Usage: "measure upload speed",
+ Action: wrapCliCommand("upload-speed", uploadSpeedCmd),
+ },
+ {
+ Name: "sliding_window",
+ Aliases: []string{"s"},
+ Usage: "measure network aggregate capacity",
+ Action: wrapCliCommand("sliding-window", slidingWindowCmd),
+ },
+ }
+
+ sort.Sort(cli.FlagsByName(app.Flags))
+ sort.Sort(cli.CommandsByName(app.Commands))
+
+ app.Before = func(ctx *cli.Context) error {
+ tracing.Setup(ctx)
+ return nil
+ }
+
+ app.After = func(ctx *cli.Context) error {
+ return emitMetrics(ctx)
+ }
+
+ err := app.Run(os.Args)
+ if err != nil {
+ log.Error(err.Error())
+
+ os.Exit(1)
+ }
+}
+
+func emitMetrics(ctx *cli.Context) error {
+ if gethmetrics.Enabled {
+ var (
+ endpoint = ctx.GlobalString(swarmmetrics.MetricsInfluxDBEndpointFlag.Name)
+ database = ctx.GlobalString(swarmmetrics.MetricsInfluxDBDatabaseFlag.Name)
+ username = ctx.GlobalString(swarmmetrics.MetricsInfluxDBUsernameFlag.Name)
+ password = ctx.GlobalString(swarmmetrics.MetricsInfluxDBPasswordFlag.Name)
+ tags = ctx.GlobalString(swarmmetrics.MetricsInfluxDBTagsFlag.Name)
+ )
+
+ tagsMap := utils.SplitTagsFlag(tags)
+ tagsMap["version"] = gitCommit
+ tagsMap["filesize"] = fmt.Sprintf("%v", filesize)
+
+ return influxdb.InfluxDBWithTagsOnce(gethmetrics.DefaultRegistry, endpoint, database, username, password, "swarm-smoke.", tagsMap)
+ }
+
+ return nil
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/swarm/swarm-smoke/sliding_window.go b/vendor/github.com/ethereum/go-ethereum/cmd/swarm/swarm-smoke/sliding_window.go
new file mode 100644
index 00000000..d589124b
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/cmd/swarm/swarm-smoke/sliding_window.go
@@ -0,0 +1,145 @@
+// Copyright 2018 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// go-ethereum is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with go-ethereum. If not, see .
+
+package main
+
+import (
+ "bytes"
+ "fmt"
+ "math/rand"
+ "time"
+
+ "github.com/ethereum/go-ethereum/log"
+ "github.com/ethereum/go-ethereum/metrics"
+ "github.com/ethereum/go-ethereum/swarm/testutil"
+ "github.com/pborman/uuid"
+
+ cli "gopkg.in/urfave/cli.v1"
+)
+
+type uploadResult struct {
+ hash string
+ digest []byte
+}
+
+func slidingWindowCmd(ctx *cli.Context, tuid string) error {
+ errc := make(chan error)
+
+ go func() {
+ errc <- slidingWindow(ctx, tuid)
+ }()
+
+ err := <-errc
+ if err != nil {
+ metrics.GetOrRegisterCounter(fmt.Sprintf("%s.fail", commandName), nil).Inc(1)
+ }
+ return err
+}
+
+func slidingWindow(ctx *cli.Context, tuid string) error {
+ var hashes []uploadResult //swarm hashes of the uploads
+ nodes := len(hosts)
+ log.Info("sliding window test started", "tuid", tuid, "nodes", nodes, "filesize(kb)", filesize, "timeout", timeout)
+ uploadedBytes := 0
+ networkDepth := 0
+ errored := false
+
+outer:
+ for {
+ seed = int(time.Now().UTC().UnixNano())
+ log.Info("uploading to "+httpEndpoint(hosts[0])+" and syncing", "seed", seed)
+
+ t1 := time.Now()
+
+ randomBytes := testutil.RandomBytes(seed, filesize*1000)
+
+ hash, err := upload(randomBytes, httpEndpoint(hosts[0]))
+ if err != nil {
+ log.Error(err.Error())
+ return err
+ }
+
+ metrics.GetOrRegisterResettingTimer("sliding-window.upload-time", nil).UpdateSince(t1)
+ metrics.GetOrRegisterGauge("sliding-window.upload-depth", nil).Update(int64(len(hashes)))
+
+ fhash, err := digest(bytes.NewReader(randomBytes))
+ if err != nil {
+ log.Error(err.Error())
+ return err
+ }
+
+ log.Info("uploaded successfully", "hash", hash, "digest", fmt.Sprintf("%x", fhash), "sleeping", syncDelay)
+ hashes = append(hashes, uploadResult{hash: hash, digest: fhash})
+ time.Sleep(time.Duration(syncDelay) * time.Second)
+ uploadedBytes += filesize * 1000
+ q := make(chan struct{}, 1)
+ d := make(chan struct{})
+ defer close(q)
+ defer close(d)
+ for i, v := range hashes {
+ timeoutC := time.After(time.Duration(timeout) * time.Second)
+ errored = false
+
+ task:
+ for {
+ select {
+ case q <- struct{}{}:
+ go func() {
+ var start time.Time
+ done := false
+ for !done {
+ log.Info("trying to retrieve hash", "hash", v.hash)
+ idx := 1 + rand.Intn(len(hosts)-1)
+ ruid := uuid.New()[:8]
+ start = time.Now()
+ // fetch hangs when swarm dies out, so we have to jump through a bit more hoops to actually
+ // catch the timeout, but also allow this retry logic
+ err := fetch(v.hash, httpEndpoint(hosts[idx]), v.digest, ruid, "")
+ if err != nil {
+ log.Error("error fetching hash", "err", err)
+ continue
+ }
+ done = true
+ }
+ metrics.GetOrRegisterResettingTimer("sliding-window.single.fetch-time", nil).UpdateSince(start)
+ d <- struct{}{}
+ }()
+ case <-d:
+ <-q
+ break task
+ case <-timeoutC:
+ errored = true
+ log.Error("error retrieving hash. timeout", "hash idx", i)
+ metrics.GetOrRegisterCounter("sliding-window.single.error", nil).Inc(1)
+ break outer
+ default:
+ }
+ }
+
+ networkDepth = i
+ metrics.GetOrRegisterGauge("sliding-window.network-depth", nil).Update(int64(networkDepth))
+ log.Info("sliding window test successfully fetched file", "currentDepth", networkDepth)
+ // this test might take a long time to finish - but we'd like to see metrics while they accumulate and not just when
+ // the test finishes. therefore emit the metrics on each iteration
+ emitMetrics(ctx)
+ }
+ }
+
+ log.Info("sliding window test finished", "errored?", errored, "networkDepth", networkDepth, "networkDepth(kb)", networkDepth*filesize)
+ log.Info("stats", "uploadedFiles", len(hashes), "uploadedKb", uploadedBytes/1000, "filesizeKb", filesize)
+
+ return nil
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/swarm/swarm-smoke/upload_and_sync.go b/vendor/github.com/ethereum/go-ethereum/cmd/swarm/swarm-smoke/upload_and_sync.go
new file mode 100644
index 00000000..6c20a4fa
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/cmd/swarm/swarm-smoke/upload_and_sync.go
@@ -0,0 +1,207 @@
+// Copyright 2018 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// go-ethereum is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with go-ethereum. If not, see .
+
+package main
+
+import (
+ "bytes"
+ "context"
+ "fmt"
+ "io/ioutil"
+ "math/rand"
+ "os"
+ "strings"
+ "sync"
+ "time"
+
+ "github.com/ethereum/go-ethereum/log"
+ "github.com/ethereum/go-ethereum/metrics"
+ "github.com/ethereum/go-ethereum/rpc"
+ "github.com/ethereum/go-ethereum/swarm/api"
+ "github.com/ethereum/go-ethereum/swarm/storage"
+ "github.com/ethereum/go-ethereum/swarm/testutil"
+ "github.com/pborman/uuid"
+
+ cli "gopkg.in/urfave/cli.v1"
+)
+
+func uploadAndSyncCmd(ctx *cli.Context, tuid string) error {
+ // use input seed if it has been set
+ if inputSeed != 0 {
+ seed = inputSeed
+ }
+
+ randomBytes := testutil.RandomBytes(seed, filesize*1000)
+
+ errc := make(chan error)
+
+ go func() {
+ errc <- uploadAndSync(ctx, randomBytes, tuid)
+ }()
+
+ var err error
+ select {
+ case err = <-errc:
+ if err != nil {
+ metrics.GetOrRegisterCounter(fmt.Sprintf("%s.fail", commandName), nil).Inc(1)
+ }
+ case <-time.After(time.Duration(timeout) * time.Second):
+ metrics.GetOrRegisterCounter(fmt.Sprintf("%s.timeout", commandName), nil).Inc(1)
+
+ err = fmt.Errorf("timeout after %v sec", timeout)
+ }
+
+ // trigger debug functionality on randomBytes
+ e := trackChunks(randomBytes[:])
+ if e != nil {
+ log.Error(e.Error())
+ }
+
+ return err
+}
+
+func trackChunks(testData []byte) error {
+ addrs, err := getAllRefs(testData)
+ if err != nil {
+ return err
+ }
+
+ for i, ref := range addrs {
+ log.Trace(fmt.Sprintf("ref %d", i), "ref", ref)
+ }
+
+ for _, host := range hosts {
+ httpHost := fmt.Sprintf("ws://%s:%d", host, 8546)
+
+ hostChunks := []string{}
+
+ rpcClient, err := rpc.Dial(httpHost)
+ if err != nil {
+ log.Error("error dialing host", "err", err, "host", httpHost)
+ continue
+ }
+
+ var hasInfo []api.HasInfo
+ err = rpcClient.Call(&hasInfo, "bzz_has", addrs)
+ if err != nil {
+ log.Error("error calling rpc client", "err", err, "host", httpHost)
+ continue
+ }
+
+ count := 0
+ for _, info := range hasInfo {
+ if info.Has {
+ hostChunks = append(hostChunks, "1")
+ } else {
+ hostChunks = append(hostChunks, "0")
+ count++
+ }
+ }
+
+ if count == 0 {
+ log.Info("host reported to have all chunks", "host", host)
+ }
+
+ log.Trace("chunks", "chunks", strings.Join(hostChunks, ""), "host", host)
+ }
+ return nil
+}
+
+func getAllRefs(testData []byte) (storage.AddressCollection, error) {
+ datadir, err := ioutil.TempDir("", "chunk-debug")
+ if err != nil {
+ return nil, fmt.Errorf("unable to create temp dir: %v", err)
+ }
+ defer os.RemoveAll(datadir)
+ fileStore, err := storage.NewLocalFileStore(datadir, make([]byte, 32))
+ if err != nil {
+ return nil, err
+ }
+ ctx, cancel := context.WithTimeout(context.Background(), time.Duration(trackTimeout)*time.Second)
+ defer cancel()
+
+ reader := bytes.NewReader(testData)
+ return fileStore.GetAllReferences(ctx, reader, false)
+}
+
+func uploadAndSync(c *cli.Context, randomBytes []byte, tuid string) error {
+ log.Info("uploading to "+httpEndpoint(hosts[0])+" and syncing", "tuid", tuid, "seed", seed)
+
+ t1 := time.Now()
+ hash, err := upload(randomBytes, httpEndpoint(hosts[0]))
+ if err != nil {
+ log.Error(err.Error())
+ return err
+ }
+ t2 := time.Since(t1)
+ metrics.GetOrRegisterResettingTimer("upload-and-sync.upload-time", nil).Update(t2)
+
+ fhash, err := digest(bytes.NewReader(randomBytes))
+ if err != nil {
+ log.Error(err.Error())
+ return err
+ }
+
+ log.Info("uploaded successfully", "tuid", tuid, "hash", hash, "took", t2, "digest", fmt.Sprintf("%x", fhash))
+
+ time.Sleep(time.Duration(syncDelay) * time.Second)
+
+ wg := sync.WaitGroup{}
+ if single {
+ randIndex := 1 + rand.Intn(len(hosts)-1)
+ ruid := uuid.New()[:8]
+ wg.Add(1)
+ go func(endpoint string, ruid string) {
+ for {
+ start := time.Now()
+ err := fetch(hash, endpoint, fhash, ruid, tuid)
+ if err != nil {
+ continue
+ }
+ ended := time.Since(start)
+
+ metrics.GetOrRegisterResettingTimer("upload-and-sync.single.fetch-time", nil).Update(ended)
+ log.Info("fetch successful", "tuid", tuid, "ruid", ruid, "took", ended, "endpoint", endpoint)
+ wg.Done()
+ return
+ }
+ }(httpEndpoint(hosts[randIndex]), ruid)
+ } else {
+ for _, endpoint := range hosts[1:] {
+ ruid := uuid.New()[:8]
+ wg.Add(1)
+ go func(endpoint string, ruid string) {
+ for {
+ start := time.Now()
+ err := fetch(hash, endpoint, fhash, ruid, tuid)
+ if err != nil {
+ continue
+ }
+ ended := time.Since(start)
+
+ metrics.GetOrRegisterResettingTimer("upload-and-sync.each.fetch-time", nil).Update(ended)
+ log.Info("fetch successful", "tuid", tuid, "ruid", ruid, "took", ended, "endpoint", endpoint)
+ wg.Done()
+ return
+ }
+ }(httpEndpoint(endpoint), ruid)
+ }
+ }
+ wg.Wait()
+ log.Info("all hosts synced random file successfully")
+
+ return nil
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/swarm/swarm-smoke/upload_speed.go b/vendor/github.com/ethereum/go-ethereum/cmd/swarm/swarm-smoke/upload_speed.go
new file mode 100644
index 00000000..20bf7b86
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/cmd/swarm/swarm-smoke/upload_speed.go
@@ -0,0 +1,73 @@
+// Copyright 2018 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// go-ethereum is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with go-ethereum. If not, see .
+
+package main
+
+import (
+ "bytes"
+ "fmt"
+ "time"
+
+ "github.com/ethereum/go-ethereum/log"
+ "github.com/ethereum/go-ethereum/metrics"
+ "github.com/ethereum/go-ethereum/swarm/testutil"
+
+ cli "gopkg.in/urfave/cli.v1"
+)
+
+func uploadSpeedCmd(ctx *cli.Context, tuid string) error {
+ log.Info("uploading to "+hosts[0], "tuid", tuid, "seed", seed)
+ randomBytes := testutil.RandomBytes(seed, filesize*1000)
+
+ errc := make(chan error)
+
+ go func() {
+ errc <- uploadSpeed(ctx, tuid, randomBytes)
+ }()
+
+ select {
+ case err := <-errc:
+ if err != nil {
+ metrics.GetOrRegisterCounter(fmt.Sprintf("%s.fail", commandName), nil).Inc(1)
+ }
+ return err
+ case <-time.After(time.Duration(timeout) * time.Second):
+ metrics.GetOrRegisterCounter(fmt.Sprintf("%s.timeout", commandName), nil).Inc(1)
+
+ // trigger debug functionality on randomBytes
+
+ return fmt.Errorf("timeout after %v sec", timeout)
+ }
+}
+
+func uploadSpeed(c *cli.Context, tuid string, data []byte) error {
+ t1 := time.Now()
+ hash, err := upload(data, hosts[0])
+ if err != nil {
+ log.Error(err.Error())
+ return err
+ }
+ metrics.GetOrRegisterCounter("upload-speed.upload-time", nil).Inc(int64(time.Since(t1)))
+
+ fhash, err := digest(bytes.NewReader(data))
+ if err != nil {
+ log.Error(err.Error())
+ return err
+ }
+
+ log.Info("uploaded successfully", "hash", hash, "digest", fmt.Sprintf("%x", fhash))
+ return nil
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/swarm/swarm-smoke/util.go b/vendor/github.com/ethereum/go-ethereum/cmd/swarm/swarm-smoke/util.go
new file mode 100644
index 00000000..87abb44b
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/cmd/swarm/swarm-smoke/util.go
@@ -0,0 +1,235 @@
+// Copyright 2018 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// go-ethereum is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with go-ethereum. If not, see .
+
+package main
+
+import (
+ "bytes"
+ "context"
+ "crypto/md5"
+ crand "crypto/rand"
+ "errors"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "math/rand"
+ "net/http"
+ "net/http/httptrace"
+ "os"
+ "strings"
+ "time"
+
+ "github.com/ethereum/go-ethereum/log"
+ "github.com/ethereum/go-ethereum/metrics"
+ "github.com/ethereum/go-ethereum/swarm/api"
+ "github.com/ethereum/go-ethereum/swarm/api/client"
+ "github.com/ethereum/go-ethereum/swarm/spancontext"
+ opentracing "github.com/opentracing/opentracing-go"
+ "github.com/pborman/uuid"
+ cli "gopkg.in/urfave/cli.v1"
+)
+
+var (
+ commandName = ""
+ seed = int(time.Now().UTC().UnixNano())
+)
+
+func init() {
+ rand.Seed(int64(seed))
+}
+
+func httpEndpoint(host string) string {
+ return fmt.Sprintf("http://%s:%d", host, httpPort)
+}
+
+func wsEndpoint(host string) string {
+ return fmt.Sprintf("ws://%s:%d", host, wsPort)
+}
+
+func wrapCliCommand(name string, command func(*cli.Context, string) error) func(*cli.Context) error {
+ return func(ctx *cli.Context) error {
+ log.PrintOrigins(true)
+ log.Root().SetHandler(log.LvlFilterHandler(log.Lvl(verbosity), log.StreamHandler(os.Stdout, log.TerminalFormat(false))))
+
+ // test uuid
+ tuid := uuid.New()[:8]
+
+ commandName = name
+
+ hosts = strings.Split(allhosts, ",")
+
+ defer func(now time.Time) {
+ totalTime := time.Since(now)
+ log.Info("total time", "tuid", tuid, "time", totalTime, "kb", filesize)
+ metrics.GetOrRegisterResettingTimer(name+".total-time", nil).Update(totalTime)
+ }(time.Now())
+
+ log.Info("smoke test starting", "tuid", tuid, "task", name, "timeout", timeout)
+ metrics.GetOrRegisterCounter(name, nil).Inc(1)
+
+ return command(ctx, tuid)
+ }
+}
+
+func fetchFeed(topic string, user string, endpoint string, original []byte, ruid string) error {
+ ctx, sp := spancontext.StartSpan(context.Background(), "feed-and-sync.fetch")
+ defer sp.Finish()
+
+ log.Trace("sleeping", "ruid", ruid)
+ time.Sleep(3 * time.Second)
+
+ log.Trace("http get request (feed)", "ruid", ruid, "api", endpoint, "topic", topic, "user", user)
+
+ var tn time.Time
+ reqUri := endpoint + "/bzz-feed:/?topic=" + topic + "&user=" + user
+ req, _ := http.NewRequest("GET", reqUri, nil)
+
+ opentracing.GlobalTracer().Inject(
+ sp.Context(),
+ opentracing.HTTPHeaders,
+ opentracing.HTTPHeadersCarrier(req.Header))
+
+ trace := client.GetClientTrace("feed-and-sync - http get", "feed-and-sync", ruid, &tn)
+
+ req = req.WithContext(httptrace.WithClientTrace(ctx, trace))
+ transport := http.DefaultTransport
+
+ //transport.TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
+
+ tn = time.Now()
+ res, err := transport.RoundTrip(req)
+ if err != nil {
+ log.Error(err.Error(), "ruid", ruid)
+ return err
+ }
+
+ log.Trace("http get response (feed)", "ruid", ruid, "api", endpoint, "topic", topic, "user", user, "code", res.StatusCode, "len", res.ContentLength)
+
+ if res.StatusCode != 200 {
+ return fmt.Errorf("expected status code %d, got %v (ruid %v)", 200, res.StatusCode, ruid)
+ }
+
+ defer res.Body.Close()
+
+ rdigest, err := digest(res.Body)
+ if err != nil {
+ log.Warn(err.Error(), "ruid", ruid)
+ return err
+ }
+
+ if !bytes.Equal(rdigest, original) {
+ err := fmt.Errorf("downloaded imported file md5=%x is not the same as the generated one=%x", rdigest, original)
+ log.Warn(err.Error(), "ruid", ruid)
+ return err
+ }
+
+ log.Trace("downloaded file matches random file", "ruid", ruid, "len", res.ContentLength)
+
+ return nil
+}
+
+// fetch is getting the requested `hash` from the `endpoint` and compares it with the `original` file
+func fetch(hash string, endpoint string, original []byte, ruid string, tuid string) error {
+ ctx, sp := spancontext.StartSpan(context.Background(), "upload-and-sync.fetch")
+ defer sp.Finish()
+
+ log.Info("http get request", "tuid", tuid, "ruid", ruid, "endpoint", endpoint, "hash", hash)
+
+ var tn time.Time
+ reqUri := endpoint + "/bzz:/" + hash + "/"
+ req, _ := http.NewRequest("GET", reqUri, nil)
+
+ opentracing.GlobalTracer().Inject(
+ sp.Context(),
+ opentracing.HTTPHeaders,
+ opentracing.HTTPHeadersCarrier(req.Header))
+
+ trace := client.GetClientTrace(commandName+" - http get", commandName, ruid, &tn)
+
+ req = req.WithContext(httptrace.WithClientTrace(ctx, trace))
+ transport := http.DefaultTransport
+
+ //transport.TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
+
+ tn = time.Now()
+ res, err := transport.RoundTrip(req)
+ if err != nil {
+ log.Error(err.Error(), "ruid", ruid)
+ return err
+ }
+ log.Info("http get response", "tuid", tuid, "ruid", ruid, "endpoint", endpoint, "hash", hash, "code", res.StatusCode, "len", res.ContentLength)
+
+ if res.StatusCode != 200 {
+ err := fmt.Errorf("expected status code %d, got %v", 200, res.StatusCode)
+ log.Warn(err.Error(), "ruid", ruid)
+ return err
+ }
+
+ defer res.Body.Close()
+
+ rdigest, err := digest(res.Body)
+ if err != nil {
+ log.Warn(err.Error(), "ruid", ruid)
+ return err
+ }
+
+ if !bytes.Equal(rdigest, original) {
+ err := fmt.Errorf("downloaded imported file md5=%x is not the same as the generated one=%x", rdigest, original)
+ log.Warn(err.Error(), "ruid", ruid)
+ return err
+ }
+
+ log.Trace("downloaded file matches random file", "ruid", ruid, "len", res.ContentLength)
+
+ return nil
+}
+
+// upload an arbitrary byte as a plaintext file to `endpoint` using the api client
+func upload(data []byte, endpoint string) (string, error) {
+ swarm := client.NewClient(endpoint)
+ f := &client.File{
+ ReadCloser: ioutil.NopCloser(bytes.NewReader(data)),
+ ManifestEntry: api.ManifestEntry{
+ ContentType: "text/plain",
+ Mode: 0660,
+ Size: int64(len(data)),
+ },
+ }
+
+ // upload data to bzz:// and retrieve the content-addressed manifest hash, hex-encoded.
+ return swarm.Upload(f, "", false)
+}
+
+func digest(r io.Reader) ([]byte, error) {
+ h := md5.New()
+ _, err := io.Copy(h, r)
+ if err != nil {
+ return nil, err
+ }
+ return h.Sum(nil), nil
+}
+
+// generates random data in heap buffer
+func generateRandomData(datasize int) ([]byte, error) {
+ b := make([]byte, datasize)
+ c, err := crand.Read(b)
+ if err != nil {
+ return nil, err
+ } else if c != datasize {
+ return nil, errors.New("short read")
+ }
+ return b, nil
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/swarm/swarm-snapshot/create.go b/vendor/github.com/ethereum/go-ethereum/cmd/swarm/swarm-snapshot/create.go
new file mode 100644
index 00000000..434561a4
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/cmd/swarm/swarm-snapshot/create.go
@@ -0,0 +1,160 @@
+// Copyright 2018 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// go-ethereum is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with go-ethereum. If not, see .
+
+package main
+
+import (
+ "context"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "io/ioutil"
+ "os"
+ "path"
+ "path/filepath"
+ "strings"
+ "sync"
+ "time"
+
+ "github.com/ethereum/go-ethereum/log"
+ "github.com/ethereum/go-ethereum/node"
+ "github.com/ethereum/go-ethereum/p2p/simulations"
+ "github.com/ethereum/go-ethereum/p2p/simulations/adapters"
+ "github.com/ethereum/go-ethereum/swarm/network"
+ "github.com/ethereum/go-ethereum/swarm/network/simulation"
+ cli "gopkg.in/urfave/cli.v1"
+)
+
+// create is used as the entry function for "create" app command.
+func create(ctx *cli.Context) error {
+ log.PrintOrigins(true)
+ log.Root().SetHandler(log.LvlFilterHandler(log.Lvl(ctx.Int("verbosity")), log.StreamHandler(os.Stdout, log.TerminalFormat(true))))
+
+ if len(ctx.Args()) < 1 {
+ return errors.New("argument should be the filename to verify or write-to")
+ }
+ filename, err := touchPath(ctx.Args()[0])
+ if err != nil {
+ return err
+ }
+ return createSnapshot(filename, ctx.Int("nodes"), strings.Split(ctx.String("services"), ","))
+}
+
+// createSnapshot creates a new snapshot on filesystem with provided filename,
+// number of nodes and service names.
+func createSnapshot(filename string, nodes int, services []string) (err error) {
+ log.Debug("create snapshot", "filename", filename, "nodes", nodes, "services", services)
+
+ sim := simulation.New(map[string]simulation.ServiceFunc{
+ "bzz": func(ctx *adapters.ServiceContext, bucket *sync.Map) (node.Service, func(), error) {
+ addr := network.NewAddr(ctx.Config.Node())
+ kad := network.NewKademlia(addr.Over(), network.NewKadParams())
+ hp := network.NewHiveParams()
+ hp.KeepAliveInterval = time.Duration(200) * time.Millisecond
+ hp.Discovery = true // discovery must be enabled when creating a snapshot
+
+ // store the kademlia in the bucket, needed later in the WaitTillHealthy function
+ bucket.Store(simulation.BucketKeyKademlia, kad)
+
+ config := &network.BzzConfig{
+ OverlayAddr: addr.Over(),
+ UnderlayAddr: addr.Under(),
+ HiveParams: hp,
+ }
+ return network.NewBzz(config, kad, nil, nil, nil), nil, nil
+ },
+ })
+ defer sim.Close()
+
+ ids, err := sim.AddNodes(nodes)
+ if err != nil {
+ return fmt.Errorf("add nodes: %v", err)
+ }
+
+ err = sim.Net.ConnectNodesRing(ids)
+ if err != nil {
+ return fmt.Errorf("connect nodes: %v", err)
+ }
+
+ ctx, cancelSimRun := context.WithTimeout(context.Background(), 3*time.Minute)
+ defer cancelSimRun()
+ if _, err := sim.WaitTillHealthy(ctx); err != nil {
+ return fmt.Errorf("wait for healthy kademlia: %v", err)
+ }
+
+ var snap *simulations.Snapshot
+ if len(services) > 0 {
+ // If service names are provided, include them in the snapshot.
+ // But, check if "bzz" service is not among them to remove it
+ // form the snapshot as it exists on snapshot creation.
+ var removeServices []string
+ var wantBzz bool
+ for _, s := range services {
+ if s == "bzz" {
+ wantBzz = true
+ break
+ }
+ }
+ if !wantBzz {
+ removeServices = []string{"bzz"}
+ }
+ snap, err = sim.Net.SnapshotWithServices(services, removeServices)
+ } else {
+ snap, err = sim.Net.Snapshot()
+ }
+ if err != nil {
+ return fmt.Errorf("create snapshot: %v", err)
+ }
+ jsonsnapshot, err := json.Marshal(snap)
+ if err != nil {
+ return fmt.Errorf("json encode snapshot: %v", err)
+ }
+ return ioutil.WriteFile(filename, jsonsnapshot, 0666)
+}
+
+// touchPath creates an empty file and all subdirectories
+// that are missing.
+func touchPath(filename string) (string, error) {
+ if path.IsAbs(filename) {
+ if _, err := os.Stat(filename); err == nil {
+ // path exists, overwrite
+ return filename, nil
+ }
+ }
+
+ d, f := path.Split(filename)
+ dir, err := filepath.Abs(filepath.Dir(os.Args[0]))
+ if err != nil {
+ return "", err
+ }
+
+ _, err = os.Stat(path.Join(dir, filename))
+ if err == nil {
+ // path exists, overwrite
+ return filename, nil
+ }
+
+ dirPath := path.Join(dir, d)
+ filePath := path.Join(dirPath, f)
+ if d != "" {
+ err = os.MkdirAll(dirPath, os.ModeDir)
+ if err != nil {
+ return "", err
+ }
+ }
+
+ return filePath, nil
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/swarm/swarm-snapshot/main.go b/vendor/github.com/ethereum/go-ethereum/cmd/swarm/swarm-snapshot/main.go
new file mode 100644
index 00000000..136295e5
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/cmd/swarm/swarm-snapshot/main.go
@@ -0,0 +1,82 @@
+// Copyright 2018 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// go-ethereum is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with go-ethereum. If not, see .
+
+package main
+
+import (
+ "os"
+
+ "github.com/ethereum/go-ethereum/cmd/utils"
+ "github.com/ethereum/go-ethereum/log"
+ cli "gopkg.in/urfave/cli.v1"
+)
+
+var gitCommit string // Git SHA1 commit hash of the release (set via linker flags)
+
+// default value for "create" command --nodes flag
+const defaultNodes = 8
+
+func main() {
+ err := newApp().Run(os.Args)
+ if err != nil {
+ log.Error(err.Error())
+ os.Exit(1)
+ }
+}
+
+// newApp construct a new instance of Swarm Snapshot Utility.
+// Method Run is called on it in the main function and in tests.
+func newApp() (app *cli.App) {
+ app = utils.NewApp(gitCommit, "Swarm Snapshot Utility")
+
+ app.Name = "swarm-snapshot"
+ app.Usage = ""
+
+ // app flags (for all commands)
+ app.Flags = []cli.Flag{
+ cli.IntFlag{
+ Name: "verbosity",
+ Value: 1,
+ Usage: "verbosity level",
+ },
+ }
+
+ app.Commands = []cli.Command{
+ {
+ Name: "create",
+ Aliases: []string{"c"},
+ Usage: "create a swarm snapshot",
+ Action: create,
+ // Flags only for "create" command.
+ // Allow app flags to be specified after the
+ // command argument.
+ Flags: append(app.Flags,
+ cli.IntFlag{
+ Name: "nodes",
+ Value: defaultNodes,
+ Usage: "number of nodes",
+ },
+ cli.StringFlag{
+ Name: "services",
+ Value: "bzz",
+ Usage: "comma separated list of services to boot the nodes with",
+ },
+ ),
+ },
+ }
+
+ return app
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/swarm/upload.go b/vendor/github.com/ethereum/go-ethereum/cmd/swarm/upload.go
new file mode 100644
index 00000000..ab079083
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/cmd/swarm/upload.go
@@ -0,0 +1,188 @@
+// Copyright 2016 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// go-ethereum is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with go-ethereum. If not, see .
+
+// Command bzzup uploads files to the swarm HTTP API.
+package main
+
+import (
+ "errors"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "os"
+ "os/user"
+ "path"
+ "path/filepath"
+ "strconv"
+ "strings"
+
+ "github.com/ethereum/go-ethereum/log"
+ swarm "github.com/ethereum/go-ethereum/swarm/api/client"
+
+ "github.com/ethereum/go-ethereum/cmd/utils"
+ "gopkg.in/urfave/cli.v1"
+)
+
+var upCommand = cli.Command{
+ Action: upload,
+ CustomHelpTemplate: helpTemplate,
+ Name: "up",
+ Usage: "uploads a file or directory to swarm using the HTTP API",
+ ArgsUsage: "",
+ Flags: []cli.Flag{SwarmEncryptedFlag},
+ Description: "uploads a file or directory to swarm using the HTTP API and prints the root hash",
+}
+
+func upload(ctx *cli.Context) {
+ args := ctx.Args()
+ var (
+ bzzapi = strings.TrimRight(ctx.GlobalString(SwarmApiFlag.Name), "/")
+ recursive = ctx.GlobalBool(SwarmRecursiveFlag.Name)
+ wantManifest = ctx.GlobalBoolT(SwarmWantManifestFlag.Name)
+ defaultPath = ctx.GlobalString(SwarmUploadDefaultPath.Name)
+ fromStdin = ctx.GlobalBool(SwarmUpFromStdinFlag.Name)
+ mimeType = ctx.GlobalString(SwarmUploadMimeType.Name)
+ client = swarm.NewClient(bzzapi)
+ toEncrypt = ctx.Bool(SwarmEncryptedFlag.Name)
+ autoDefaultPath = false
+ file string
+ )
+ if autoDefaultPathString := os.Getenv(SwarmAutoDefaultPath); autoDefaultPathString != "" {
+ b, err := strconv.ParseBool(autoDefaultPathString)
+ if err != nil {
+ utils.Fatalf("invalid environment variable %s: %v", SwarmAutoDefaultPath, err)
+ }
+ autoDefaultPath = b
+ }
+ if len(args) != 1 {
+ if fromStdin {
+ tmp, err := ioutil.TempFile("", "swarm-stdin")
+ if err != nil {
+ utils.Fatalf("error create tempfile: %s", err)
+ }
+ defer os.Remove(tmp.Name())
+ n, err := io.Copy(tmp, os.Stdin)
+ if err != nil {
+ utils.Fatalf("error copying stdin to tempfile: %s", err)
+ } else if n == 0 {
+ utils.Fatalf("error reading from stdin: zero length")
+ }
+ file = tmp.Name()
+ } else {
+ utils.Fatalf("Need filename as the first and only argument")
+ }
+ } else {
+ file = expandPath(args[0])
+ }
+
+ if !wantManifest {
+ f, err := swarm.Open(file)
+ if err != nil {
+ utils.Fatalf("Error opening file: %s", err)
+ }
+ defer f.Close()
+ hash, err := client.UploadRaw(f, f.Size, toEncrypt)
+ if err != nil {
+ utils.Fatalf("Upload failed: %s", err)
+ }
+ fmt.Println(hash)
+ return
+ }
+
+ stat, err := os.Stat(file)
+ if err != nil {
+ utils.Fatalf("Error opening file: %s", err)
+ }
+
+ // define a function which either uploads a directory or single file
+ // based on the type of the file being uploaded
+ var doUpload func() (hash string, err error)
+ if stat.IsDir() {
+ doUpload = func() (string, error) {
+ if !recursive {
+ return "", errors.New("Argument is a directory and recursive upload is disabled")
+ }
+ if autoDefaultPath && defaultPath == "" {
+ defaultEntryCandidate := path.Join(file, "index.html")
+ log.Debug("trying to find default path", "path", defaultEntryCandidate)
+ defaultEntryStat, err := os.Stat(defaultEntryCandidate)
+ if err == nil && !defaultEntryStat.IsDir() {
+ log.Debug("setting auto detected default path", "path", defaultEntryCandidate)
+ defaultPath = defaultEntryCandidate
+ }
+ }
+ if defaultPath != "" {
+ // construct absolute default path
+ absDefaultPath, _ := filepath.Abs(defaultPath)
+ absFile, _ := filepath.Abs(file)
+ // make sure absolute directory ends with only one "/"
+ // to trim it from absolute default path and get relative default path
+ absFile = strings.TrimRight(absFile, "/") + "/"
+ if absDefaultPath != "" && absFile != "" && strings.HasPrefix(absDefaultPath, absFile) {
+ defaultPath = strings.TrimPrefix(absDefaultPath, absFile)
+ }
+ }
+ return client.UploadDirectory(file, defaultPath, "", toEncrypt)
+ }
+ } else {
+ doUpload = func() (string, error) {
+ f, err := swarm.Open(file)
+ if err != nil {
+ return "", fmt.Errorf("error opening file: %s", err)
+ }
+ defer f.Close()
+ if mimeType != "" {
+ f.ContentType = mimeType
+ }
+ return client.Upload(f, "", toEncrypt)
+ }
+ }
+ hash, err := doUpload()
+ if err != nil {
+ utils.Fatalf("Upload failed: %s", err)
+ }
+ fmt.Println(hash)
+}
+
+// Expands a file path
+// 1. replace tilde with users home dir
+// 2. expands embedded environment variables
+// 3. cleans the path, e.g. /a/b/../c -> /a/c
+// Note, it has limitations, e.g. ~someuser/tmp will not be expanded
+func expandPath(p string) string {
+ if i := strings.Index(p, ":"); i > 0 {
+ return p
+ }
+ if i := strings.Index(p, "@"); i > 0 {
+ return p
+ }
+ if strings.HasPrefix(p, "~/") || strings.HasPrefix(p, "~\\") {
+ if home := homeDir(); home != "" {
+ p = home + p[1:]
+ }
+ }
+ return path.Clean(os.ExpandEnv(p))
+}
+
+func homeDir() string {
+ if home := os.Getenv("HOME"); home != "" {
+ return home
+ }
+ if usr, err := user.Current(); err == nil {
+ return usr.HomeDir
+ }
+ return ""
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/utils/cmd.go b/vendor/github.com/ethereum/go-ethereum/cmd/utils/cmd.go
new file mode 100644
index 00000000..74a8c7f3
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/cmd/utils/cmd.go
@@ -0,0 +1,312 @@
+// Copyright 2014 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// go-ethereum is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with go-ethereum. If not, see .
+
+// Package utils contains internal helper functions for go-ethereum commands.
+package utils
+
+import (
+ "compress/gzip"
+ "fmt"
+ "io"
+ "os"
+ "os/signal"
+ "runtime"
+ "strings"
+ "syscall"
+
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/core"
+ "github.com/ethereum/go-ethereum/core/rawdb"
+ "github.com/ethereum/go-ethereum/core/types"
+ "github.com/ethereum/go-ethereum/crypto"
+ "github.com/ethereum/go-ethereum/ethdb"
+ "github.com/ethereum/go-ethereum/internal/debug"
+ "github.com/ethereum/go-ethereum/log"
+ "github.com/ethereum/go-ethereum/node"
+ "github.com/ethereum/go-ethereum/rlp"
+)
+
+const (
+ importBatchSize = 2500
+)
+
+// Fatalf formats a message to standard error and exits the program.
+// The message is also printed to standard output if standard error
+// is redirected to a different file.
+func Fatalf(format string, args ...interface{}) {
+ w := io.MultiWriter(os.Stdout, os.Stderr)
+ if runtime.GOOS == "windows" {
+ // The SameFile check below doesn't work on Windows.
+ // stdout is unlikely to get redirected though, so just print there.
+ w = os.Stdout
+ } else {
+ outf, _ := os.Stdout.Stat()
+ errf, _ := os.Stderr.Stat()
+ if outf != nil && errf != nil && os.SameFile(outf, errf) {
+ w = os.Stderr
+ }
+ }
+ fmt.Fprintf(w, "Fatal: "+format+"\n", args...)
+ os.Exit(1)
+}
+
+func StartNode(stack *node.Node) {
+ if err := stack.Start(); err != nil {
+ Fatalf("Error starting protocol stack: %v", err)
+ }
+ go func() {
+ sigc := make(chan os.Signal, 1)
+ signal.Notify(sigc, syscall.SIGINT, syscall.SIGTERM)
+ defer signal.Stop(sigc)
+ <-sigc
+ log.Info("Got interrupt, shutting down...")
+ go stack.Stop()
+ for i := 10; i > 0; i-- {
+ <-sigc
+ if i > 1 {
+ log.Warn("Already shutting down, interrupt more to panic.", "times", i-1)
+ }
+ }
+ debug.Exit() // ensure trace and CPU profile data is flushed.
+ debug.LoudPanic("boom")
+ }()
+}
+
+func ImportChain(chain *core.BlockChain, fn string) error {
+ // Watch for Ctrl-C while the import is running.
+ // If a signal is received, the import will stop at the next batch.
+ interrupt := make(chan os.Signal, 1)
+ stop := make(chan struct{})
+ signal.Notify(interrupt, syscall.SIGINT, syscall.SIGTERM)
+ defer signal.Stop(interrupt)
+ defer close(interrupt)
+ go func() {
+ if _, ok := <-interrupt; ok {
+ log.Info("Interrupted during import, stopping at next batch")
+ }
+ close(stop)
+ }()
+ checkInterrupt := func() bool {
+ select {
+ case <-stop:
+ return true
+ default:
+ return false
+ }
+ }
+
+ log.Info("Importing blockchain", "file", fn)
+
+ // Open the file handle and potentially unwrap the gzip stream
+ fh, err := os.Open(fn)
+ if err != nil {
+ return err
+ }
+ defer fh.Close()
+
+ var reader io.Reader = fh
+ if strings.HasSuffix(fn, ".gz") {
+ if reader, err = gzip.NewReader(reader); err != nil {
+ return err
+ }
+ }
+ stream := rlp.NewStream(reader, 0)
+
+ // Run actual the import.
+ blocks := make(types.Blocks, importBatchSize)
+ n := 0
+ for batch := 0; ; batch++ {
+ // Load a batch of RLP blocks.
+ if checkInterrupt() {
+ return fmt.Errorf("interrupted")
+ }
+ i := 0
+ for ; i < importBatchSize; i++ {
+ var b types.Block
+ if err := stream.Decode(&b); err == io.EOF {
+ break
+ } else if err != nil {
+ return fmt.Errorf("at block %d: %v", n, err)
+ }
+ // don't import first block
+ if b.NumberU64() == 0 {
+ i--
+ continue
+ }
+ blocks[i] = &b
+ n++
+ }
+ if i == 0 {
+ break
+ }
+ // Import the batch.
+ if checkInterrupt() {
+ return fmt.Errorf("interrupted")
+ }
+ missing := missingBlocks(chain, blocks[:i])
+ if len(missing) == 0 {
+ log.Info("Skipping batch as all blocks present", "batch", batch, "first", blocks[0].Hash(), "last", blocks[i-1].Hash())
+ continue
+ }
+ if _, err := chain.InsertChain(missing); err != nil {
+ return fmt.Errorf("invalid block %d: %v", n, err)
+ }
+ }
+ return nil
+}
+
+func missingBlocks(chain *core.BlockChain, blocks []*types.Block) []*types.Block {
+ head := chain.CurrentBlock()
+ for i, block := range blocks {
+ // If we're behind the chain head, only check block, state is available at head
+ if head.NumberU64() > block.NumberU64() {
+ if !chain.HasBlock(block.Hash(), block.NumberU64()) {
+ return blocks[i:]
+ }
+ continue
+ }
+ // If we're above the chain head, state availability is a must
+ if !chain.HasBlockAndState(block.Hash(), block.NumberU64()) {
+ return blocks[i:]
+ }
+ }
+ return nil
+}
+
+// ExportChain exports a blockchain into the specified file, truncating any data
+// already present in the file.
+func ExportChain(blockchain *core.BlockChain, fn string) error {
+ log.Info("Exporting blockchain", "file", fn)
+
+ // Open the file handle and potentially wrap with a gzip stream
+ fh, err := os.OpenFile(fn, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, os.ModePerm)
+ if err != nil {
+ return err
+ }
+ defer fh.Close()
+
+ var writer io.Writer = fh
+ if strings.HasSuffix(fn, ".gz") {
+ writer = gzip.NewWriter(writer)
+ defer writer.(*gzip.Writer).Close()
+ }
+ // Iterate over the blocks and export them
+ if err := blockchain.Export(writer); err != nil {
+ return err
+ }
+ log.Info("Exported blockchain", "file", fn)
+
+ return nil
+}
+
+// ExportAppendChain exports a blockchain into the specified file, appending to
+// the file if data already exists in it.
+func ExportAppendChain(blockchain *core.BlockChain, fn string, first uint64, last uint64) error {
+ log.Info("Exporting blockchain", "file", fn)
+
+ // Open the file handle and potentially wrap with a gzip stream
+ fh, err := os.OpenFile(fn, os.O_CREATE|os.O_APPEND|os.O_WRONLY, os.ModePerm)
+ if err != nil {
+ return err
+ }
+ defer fh.Close()
+
+ var writer io.Writer = fh
+ if strings.HasSuffix(fn, ".gz") {
+ writer = gzip.NewWriter(writer)
+ defer writer.(*gzip.Writer).Close()
+ }
+ // Iterate over the blocks and export them
+ if err := blockchain.ExportN(writer, first, last); err != nil {
+ return err
+ }
+ log.Info("Exported blockchain to", "file", fn)
+ return nil
+}
+
+// ImportPreimages imports a batch of exported hash preimages into the database.
+func ImportPreimages(db ethdb.Database, fn string) error {
+ log.Info("Importing preimages", "file", fn)
+
+ // Open the file handle and potentially unwrap the gzip stream
+ fh, err := os.Open(fn)
+ if err != nil {
+ return err
+ }
+ defer fh.Close()
+
+ var reader io.Reader = fh
+ if strings.HasSuffix(fn, ".gz") {
+ if reader, err = gzip.NewReader(reader); err != nil {
+ return err
+ }
+ }
+ stream := rlp.NewStream(reader, 0)
+
+ // Import the preimages in batches to prevent disk trashing
+ preimages := make(map[common.Hash][]byte)
+
+ for {
+ // Read the next entry and ensure it's not junk
+ var blob []byte
+
+ if err := stream.Decode(&blob); err != nil {
+ if err == io.EOF {
+ break
+ }
+ return err
+ }
+ // Accumulate the preimages and flush when enough ws gathered
+ preimages[crypto.Keccak256Hash(blob)] = common.CopyBytes(blob)
+ if len(preimages) > 1024 {
+ rawdb.WritePreimages(db, preimages)
+ preimages = make(map[common.Hash][]byte)
+ }
+ }
+ // Flush the last batch preimage data
+ if len(preimages) > 0 {
+ rawdb.WritePreimages(db, preimages)
+ }
+ return nil
+}
+
+// ExportPreimages exports all known hash preimages into the specified file,
+// truncating any data already present in the file.
+func ExportPreimages(db ethdb.Database, fn string) error {
+ log.Info("Exporting preimages", "file", fn)
+
+ // Open the file handle and potentially wrap with a gzip stream
+ fh, err := os.OpenFile(fn, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, os.ModePerm)
+ if err != nil {
+ return err
+ }
+ defer fh.Close()
+
+ var writer io.Writer = fh
+ if strings.HasSuffix(fn, ".gz") {
+ writer = gzip.NewWriter(writer)
+ defer writer.(*gzip.Writer).Close()
+ }
+ // Iterate over the preimages and export them
+ it := db.NewIteratorWithPrefix([]byte("secure-key-"))
+ for it.Next() {
+ if err := rlp.Encode(writer, it.Value()); err != nil {
+ return err
+ }
+ }
+ log.Info("Exported preimages", "file", fn)
+ return nil
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/utils/customflags.go b/vendor/github.com/ethereum/go-ethereum/cmd/utils/customflags.go
new file mode 100644
index 00000000..e5bf8724
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/cmd/utils/customflags.go
@@ -0,0 +1,240 @@
+// Copyright 2015 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// go-ethereum is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with go-ethereum. If not, see .
+
+package utils
+
+import (
+ "encoding"
+ "errors"
+ "flag"
+ "fmt"
+ "math/big"
+ "os"
+ "os/user"
+ "path"
+ "strings"
+
+ "github.com/ethereum/go-ethereum/common/math"
+ "gopkg.in/urfave/cli.v1"
+)
+
+// Custom type which is registered in the flags library which cli uses for
+// argument parsing. This allows us to expand Value to an absolute path when
+// the argument is parsed
+type DirectoryString struct {
+ Value string
+}
+
+func (self *DirectoryString) String() string {
+ return self.Value
+}
+
+func (self *DirectoryString) Set(value string) error {
+ self.Value = expandPath(value)
+ return nil
+}
+
+// Custom cli.Flag type which expand the received string to an absolute path.
+// e.g. ~/.ethereum -> /home/username/.ethereum
+type DirectoryFlag struct {
+ Name string
+ Value DirectoryString
+ Usage string
+}
+
+func (self DirectoryFlag) String() string {
+ fmtString := "%s %v\t%v"
+ if len(self.Value.Value) > 0 {
+ fmtString = "%s \"%v\"\t%v"
+ }
+ return fmt.Sprintf(fmtString, prefixedNames(self.Name), self.Value.Value, self.Usage)
+}
+
+func eachName(longName string, fn func(string)) {
+ parts := strings.Split(longName, ",")
+ for _, name := range parts {
+ name = strings.Trim(name, " ")
+ fn(name)
+ }
+}
+
+// called by cli library, grabs variable from environment (if in env)
+// and adds variable to flag set for parsing.
+func (self DirectoryFlag) Apply(set *flag.FlagSet) {
+ eachName(self.Name, func(name string) {
+ set.Var(&self.Value, self.Name, self.Usage)
+ })
+}
+
+type TextMarshaler interface {
+ encoding.TextMarshaler
+ encoding.TextUnmarshaler
+}
+
+// textMarshalerVal turns a TextMarshaler into a flag.Value
+type textMarshalerVal struct {
+ v TextMarshaler
+}
+
+func (v textMarshalerVal) String() string {
+ if v.v == nil {
+ return ""
+ }
+ text, _ := v.v.MarshalText()
+ return string(text)
+}
+
+func (v textMarshalerVal) Set(s string) error {
+ return v.v.UnmarshalText([]byte(s))
+}
+
+// TextMarshalerFlag wraps a TextMarshaler value.
+type TextMarshalerFlag struct {
+ Name string
+ Value TextMarshaler
+ Usage string
+}
+
+func (f TextMarshalerFlag) GetName() string {
+ return f.Name
+}
+
+func (f TextMarshalerFlag) String() string {
+ return fmt.Sprintf("%s \"%v\"\t%v", prefixedNames(f.Name), f.Value, f.Usage)
+}
+
+func (f TextMarshalerFlag) Apply(set *flag.FlagSet) {
+ eachName(f.Name, func(name string) {
+ set.Var(textMarshalerVal{f.Value}, f.Name, f.Usage)
+ })
+}
+
+// GlobalTextMarshaler returns the value of a TextMarshalerFlag from the global flag set.
+func GlobalTextMarshaler(ctx *cli.Context, name string) TextMarshaler {
+ val := ctx.GlobalGeneric(name)
+ if val == nil {
+ return nil
+ }
+ return val.(textMarshalerVal).v
+}
+
+// BigFlag is a command line flag that accepts 256 bit big integers in decimal or
+// hexadecimal syntax.
+type BigFlag struct {
+ Name string
+ Value *big.Int
+ Usage string
+}
+
+// bigValue turns *big.Int into a flag.Value
+type bigValue big.Int
+
+func (b *bigValue) String() string {
+ if b == nil {
+ return ""
+ }
+ return (*big.Int)(b).String()
+}
+
+func (b *bigValue) Set(s string) error {
+ int, ok := math.ParseBig256(s)
+ if !ok {
+ return errors.New("invalid integer syntax")
+ }
+ *b = (bigValue)(*int)
+ return nil
+}
+
+func (f BigFlag) GetName() string {
+ return f.Name
+}
+
+func (f BigFlag) String() string {
+ fmtString := "%s %v\t%v"
+ if f.Value != nil {
+ fmtString = "%s \"%v\"\t%v"
+ }
+ return fmt.Sprintf(fmtString, prefixedNames(f.Name), f.Value, f.Usage)
+}
+
+func (f BigFlag) Apply(set *flag.FlagSet) {
+ eachName(f.Name, func(name string) {
+ set.Var((*bigValue)(f.Value), f.Name, f.Usage)
+ })
+}
+
+// GlobalBig returns the value of a BigFlag from the global flag set.
+func GlobalBig(ctx *cli.Context, name string) *big.Int {
+ val := ctx.GlobalGeneric(name)
+ if val == nil {
+ return nil
+ }
+ return (*big.Int)(val.(*bigValue))
+}
+
+func prefixFor(name string) (prefix string) {
+ if len(name) == 1 {
+ prefix = "-"
+ } else {
+ prefix = "--"
+ }
+
+ return
+}
+
+func prefixedNames(fullName string) (prefixed string) {
+ parts := strings.Split(fullName, ",")
+ for i, name := range parts {
+ name = strings.Trim(name, " ")
+ prefixed += prefixFor(name) + name
+ if i < len(parts)-1 {
+ prefixed += ", "
+ }
+ }
+ return
+}
+
+func (self DirectoryFlag) GetName() string {
+ return self.Name
+}
+
+func (self *DirectoryFlag) Set(value string) {
+ self.Value.Value = value
+}
+
+// Expands a file path
+// 1. replace tilde with users home dir
+// 2. expands embedded environment variables
+// 3. cleans the path, e.g. /a/b/../c -> /a/c
+// Note, it has limitations, e.g. ~someuser/tmp will not be expanded
+func expandPath(p string) string {
+ if strings.HasPrefix(p, "~/") || strings.HasPrefix(p, "~\\") {
+ if home := homeDir(); home != "" {
+ p = home + p[1:]
+ }
+ }
+ return path.Clean(os.ExpandEnv(p))
+}
+
+func homeDir() string {
+ if home := os.Getenv("HOME"); home != "" {
+ return home
+ }
+ if usr, err := user.Current(); err == nil {
+ return usr.HomeDir
+ }
+ return ""
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/utils/flags.go b/vendor/github.com/ethereum/go-ethereum/cmd/utils/flags.go
new file mode 100644
index 00000000..e4bb18a8
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/cmd/utils/flags.go
@@ -0,0 +1,1699 @@
+// Copyright 2015 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// go-ethereum is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with go-ethereum. If not, see .
+
+// Package utils contains internal helper functions for go-ethereum commands.
+package utils
+
+import (
+ "crypto/ecdsa"
+ "encoding/json"
+ "fmt"
+ "io/ioutil"
+ "math/big"
+ "os"
+ "path/filepath"
+ "strconv"
+ "strings"
+ "time"
+
+ cli "gopkg.in/urfave/cli.v1"
+
+ "github.com/ethereum/go-ethereum/accounts"
+ "github.com/ethereum/go-ethereum/accounts/keystore"
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/common/fdlimit"
+ "github.com/ethereum/go-ethereum/consensus"
+ "github.com/ethereum/go-ethereum/consensus/clique"
+ "github.com/ethereum/go-ethereum/consensus/ethash"
+ "github.com/ethereum/go-ethereum/core"
+ "github.com/ethereum/go-ethereum/core/vm"
+ "github.com/ethereum/go-ethereum/crypto"
+ "github.com/ethereum/go-ethereum/dashboard"
+ "github.com/ethereum/go-ethereum/eth"
+ "github.com/ethereum/go-ethereum/eth/downloader"
+ "github.com/ethereum/go-ethereum/eth/gasprice"
+ "github.com/ethereum/go-ethereum/ethdb"
+ "github.com/ethereum/go-ethereum/ethstats"
+ "github.com/ethereum/go-ethereum/les"
+ "github.com/ethereum/go-ethereum/log"
+ "github.com/ethereum/go-ethereum/metrics"
+ "github.com/ethereum/go-ethereum/metrics/influxdb"
+ "github.com/ethereum/go-ethereum/node"
+ "github.com/ethereum/go-ethereum/p2p"
+ "github.com/ethereum/go-ethereum/p2p/discv5"
+ "github.com/ethereum/go-ethereum/p2p/enode"
+ "github.com/ethereum/go-ethereum/p2p/nat"
+ "github.com/ethereum/go-ethereum/p2p/netutil"
+ "github.com/ethereum/go-ethereum/params"
+ "github.com/ethereum/go-ethereum/statediff"
+ whisper "github.com/ethereum/go-ethereum/whisper/whisperv6"
+)
+
+var (
+ CommandHelpTemplate = `{{.cmd.Name}}{{if .cmd.Subcommands}} command{{end}}{{if .cmd.Flags}} [command options]{{end}} [arguments...]
+{{if .cmd.Description}}{{.cmd.Description}}
+{{end}}{{if .cmd.Subcommands}}
+SUBCOMMANDS:
+ {{range .cmd.Subcommands}}{{.Name}}{{with .ShortName}}, {{.}}{{end}}{{ "\t" }}{{.Usage}}
+ {{end}}{{end}}{{if .categorizedFlags}}
+{{range $idx, $categorized := .categorizedFlags}}{{$categorized.Name}} OPTIONS:
+{{range $categorized.Flags}}{{"\t"}}{{.}}
+{{end}}
+{{end}}{{end}}`
+)
+
+func init() {
+ cli.AppHelpTemplate = `{{.Name}} {{if .Flags}}[global options] {{end}}command{{if .Flags}} [command options]{{end}} [arguments...]
+
+VERSION:
+ {{.Version}}
+
+COMMANDS:
+ {{range .Commands}}{{.Name}}{{with .ShortName}}, {{.}}{{end}}{{ "\t" }}{{.Usage}}
+ {{end}}{{if .Flags}}
+GLOBAL OPTIONS:
+ {{range .Flags}}{{.}}
+ {{end}}{{end}}
+`
+
+ cli.CommandHelpTemplate = CommandHelpTemplate
+}
+
+// NewApp creates an app with sane defaults.
+func NewApp(gitCommit, usage string) *cli.App {
+ app := cli.NewApp()
+ app.Name = filepath.Base(os.Args[0])
+ app.Author = ""
+ //app.Authors = nil
+ app.Email = ""
+ app.Version = params.VersionWithMeta
+ if len(gitCommit) >= 8 {
+ app.Version += "-" + gitCommit[:8]
+ }
+ app.Usage = usage
+ return app
+}
+
+// These are all the command line flags we support.
+// If you add to this list, please remember to include the
+// flag in the appropriate command definition.
+//
+// The flags are defined here so their names and help texts
+// are the same for all commands.
+
+var (
+ // General settings
+ DataDirFlag = DirectoryFlag{
+ Name: "datadir",
+ Usage: "Data directory for the databases and keystore",
+ Value: DirectoryString{node.DefaultDataDir()},
+ }
+ KeyStoreDirFlag = DirectoryFlag{
+ Name: "keystore",
+ Usage: "Directory for the keystore (default = inside the datadir)",
+ }
+ NoUSBFlag = cli.BoolFlag{
+ Name: "nousb",
+ Usage: "Disables monitoring for and managing USB hardware wallets",
+ }
+ NetworkIdFlag = cli.Uint64Flag{
+ Name: "networkid",
+ Usage: "Network identifier (integer, 1=Frontier, 2=Morden (disused), 3=Ropsten, 4=Rinkeby)",
+ Value: eth.DefaultConfig.NetworkId,
+ }
+ TestnetFlag = cli.BoolFlag{
+ Name: "testnet",
+ Usage: "Ropsten network: pre-configured proof-of-work test network",
+ }
+ RinkebyFlag = cli.BoolFlag{
+ Name: "rinkeby",
+ Usage: "Rinkeby network: pre-configured proof-of-authority test network",
+ }
+ GoerliFlag = cli.BoolFlag{
+ Name: "goerli",
+ Usage: "Görli network: pre-configured proof-of-authority test network",
+ }
+ ConstantinopleOverrideFlag = cli.Uint64Flag{
+ Name: "override.constantinople",
+ Usage: "Manually specify constantinople fork-block, overriding the bundled setting",
+ }
+ DeveloperFlag = cli.BoolFlag{
+ Name: "dev",
+ Usage: "Ephemeral proof-of-authority network with a pre-funded developer account, mining enabled",
+ }
+ DeveloperPeriodFlag = cli.IntFlag{
+ Name: "dev.period",
+ Usage: "Block period to use in developer mode (0 = mine only if transaction pending)",
+ }
+ IdentityFlag = cli.StringFlag{
+ Name: "identity",
+ Usage: "Custom node name",
+ }
+ DocRootFlag = DirectoryFlag{
+ Name: "docroot",
+ Usage: "Document Root for HTTPClient file scheme",
+ Value: DirectoryString{homeDir()},
+ }
+ ExitWhenSyncedFlag = cli.BoolFlag{
+ Name: "exitwhensynced",
+ Usage: "Exits after block synchronisation completes",
+ }
+ ULCModeConfigFlag = cli.StringFlag{
+ Name: "ulc.config",
+ Usage: "Config file to use for ultra light client mode",
+ }
+ OnlyAnnounceModeFlag = cli.BoolFlag{
+ Name: "ulc.onlyannounce",
+ Usage: "ULC server sends announcements only",
+ }
+ ULCMinTrustedFractionFlag = cli.IntFlag{
+ Name: "ulc.fraction",
+ Usage: "Minimum % of trusted ULC servers required to announce a new head",
+ }
+ ULCTrustedNodesFlag = cli.StringFlag{
+ Name: "ulc.trusted",
+ Usage: "List of trusted ULC servers",
+ }
+ defaultSyncMode = eth.DefaultConfig.SyncMode
+ SyncModeFlag = TextMarshalerFlag{
+ Name: "syncmode",
+ Usage: `Blockchain sync mode ("fast", "full", or "light")`,
+ Value: &defaultSyncMode,
+ }
+ GCModeFlag = cli.StringFlag{
+ Name: "gcmode",
+ Usage: `Blockchain garbage collection mode ("full", "archive")`,
+ Value: "full",
+ }
+ LightServFlag = cli.IntFlag{
+ Name: "lightserv",
+ Usage: "Maximum percentage of time allowed for serving LES requests (multi-threaded processing allows values over 100)",
+ Value: 0,
+ }
+ LightBandwidthInFlag = cli.IntFlag{
+ Name: "lightbwin",
+ Usage: "Incoming bandwidth limit for light server (1000 bytes/sec, 0 = unlimited)",
+ Value: 1000,
+ }
+ LightBandwidthOutFlag = cli.IntFlag{
+ Name: "lightbwout",
+ Usage: "Outgoing bandwidth limit for light server (1000 bytes/sec, 0 = unlimited)",
+ Value: 5000,
+ }
+ LightPeersFlag = cli.IntFlag{
+ Name: "lightpeers",
+ Usage: "Maximum number of LES client peers",
+ Value: eth.DefaultConfig.LightPeers,
+ }
+ LightKDFFlag = cli.BoolFlag{
+ Name: "lightkdf",
+ Usage: "Reduce key-derivation RAM & CPU usage at some expense of KDF strength",
+ }
+ WhitelistFlag = cli.StringFlag{
+ Name: "whitelist",
+ Usage: "Comma separated block number-to-hash mappings to enforce (=)",
+ }
+ // Dashboard settings
+ DashboardEnabledFlag = cli.BoolFlag{
+ Name: "dashboard",
+ Usage: "Enable the dashboard",
+ }
+ DashboardAddrFlag = cli.StringFlag{
+ Name: "dashboard.addr",
+ Usage: "Dashboard listening interface",
+ Value: dashboard.DefaultConfig.Host,
+ }
+ DashboardPortFlag = cli.IntFlag{
+ Name: "dashboard.host",
+ Usage: "Dashboard listening port",
+ Value: dashboard.DefaultConfig.Port,
+ }
+ DashboardRefreshFlag = cli.DurationFlag{
+ Name: "dashboard.refresh",
+ Usage: "Dashboard metrics collection refresh rate",
+ Value: dashboard.DefaultConfig.Refresh,
+ }
+ // Ethash settings
+ EthashCacheDirFlag = DirectoryFlag{
+ Name: "ethash.cachedir",
+ Usage: "Directory to store the ethash verification caches (default = inside the datadir)",
+ }
+ EthashCachesInMemoryFlag = cli.IntFlag{
+ Name: "ethash.cachesinmem",
+ Usage: "Number of recent ethash caches to keep in memory (16MB each)",
+ Value: eth.DefaultConfig.Ethash.CachesInMem,
+ }
+ EthashCachesOnDiskFlag = cli.IntFlag{
+ Name: "ethash.cachesondisk",
+ Usage: "Number of recent ethash caches to keep on disk (16MB each)",
+ Value: eth.DefaultConfig.Ethash.CachesOnDisk,
+ }
+ EthashDatasetDirFlag = DirectoryFlag{
+ Name: "ethash.dagdir",
+ Usage: "Directory to store the ethash mining DAGs (default = inside home folder)",
+ Value: DirectoryString{eth.DefaultConfig.Ethash.DatasetDir},
+ }
+ EthashDatasetsInMemoryFlag = cli.IntFlag{
+ Name: "ethash.dagsinmem",
+ Usage: "Number of recent ethash mining DAGs to keep in memory (1+GB each)",
+ Value: eth.DefaultConfig.Ethash.DatasetsInMem,
+ }
+ EthashDatasetsOnDiskFlag = cli.IntFlag{
+ Name: "ethash.dagsondisk",
+ Usage: "Number of recent ethash mining DAGs to keep on disk (1+GB each)",
+ Value: eth.DefaultConfig.Ethash.DatasetsOnDisk,
+ }
+ // Transaction pool settings
+ TxPoolLocalsFlag = cli.StringFlag{
+ Name: "txpool.locals",
+ Usage: "Comma separated accounts to treat as locals (no flush, priority inclusion)",
+ }
+ TxPoolNoLocalsFlag = cli.BoolFlag{
+ Name: "txpool.nolocals",
+ Usage: "Disables price exemptions for locally submitted transactions",
+ }
+ TxPoolJournalFlag = cli.StringFlag{
+ Name: "txpool.journal",
+ Usage: "Disk journal for local transaction to survive node restarts",
+ Value: core.DefaultTxPoolConfig.Journal,
+ }
+ TxPoolRejournalFlag = cli.DurationFlag{
+ Name: "txpool.rejournal",
+ Usage: "Time interval to regenerate the local transaction journal",
+ Value: core.DefaultTxPoolConfig.Rejournal,
+ }
+ TxPoolPriceLimitFlag = cli.Uint64Flag{
+ Name: "txpool.pricelimit",
+ Usage: "Minimum gas price limit to enforce for acceptance into the pool",
+ Value: eth.DefaultConfig.TxPool.PriceLimit,
+ }
+ TxPoolPriceBumpFlag = cli.Uint64Flag{
+ Name: "txpool.pricebump",
+ Usage: "Price bump percentage to replace an already existing transaction",
+ Value: eth.DefaultConfig.TxPool.PriceBump,
+ }
+ TxPoolAccountSlotsFlag = cli.Uint64Flag{
+ Name: "txpool.accountslots",
+ Usage: "Minimum number of executable transaction slots guaranteed per account",
+ Value: eth.DefaultConfig.TxPool.AccountSlots,
+ }
+ TxPoolGlobalSlotsFlag = cli.Uint64Flag{
+ Name: "txpool.globalslots",
+ Usage: "Maximum number of executable transaction slots for all accounts",
+ Value: eth.DefaultConfig.TxPool.GlobalSlots,
+ }
+ TxPoolAccountQueueFlag = cli.Uint64Flag{
+ Name: "txpool.accountqueue",
+ Usage: "Maximum number of non-executable transaction slots permitted per account",
+ Value: eth.DefaultConfig.TxPool.AccountQueue,
+ }
+ TxPoolGlobalQueueFlag = cli.Uint64Flag{
+ Name: "txpool.globalqueue",
+ Usage: "Maximum number of non-executable transaction slots for all accounts",
+ Value: eth.DefaultConfig.TxPool.GlobalQueue,
+ }
+ TxPoolLifetimeFlag = cli.DurationFlag{
+ Name: "txpool.lifetime",
+ Usage: "Maximum amount of time non-executable transaction are queued",
+ Value: eth.DefaultConfig.TxPool.Lifetime,
+ }
+ // Performance tuning settings
+ CacheFlag = cli.IntFlag{
+ Name: "cache",
+ Usage: "Megabytes of memory allocated to internal caching",
+ Value: 1024,
+ }
+ CacheDatabaseFlag = cli.IntFlag{
+ Name: "cache.database",
+ Usage: "Percentage of cache memory allowance to use for database io",
+ Value: 50,
+ }
+ CacheTrieFlag = cli.IntFlag{
+ Name: "cache.trie",
+ Usage: "Percentage of cache memory allowance to use for trie caching (default = 25% full mode, 50% archive mode)",
+ Value: 25,
+ }
+ CacheGCFlag = cli.IntFlag{
+ Name: "cache.gc",
+ Usage: "Percentage of cache memory allowance to use for trie pruning (default = 25% full mode, 0% archive mode)",
+ Value: 25,
+ }
+ CacheNoPrefetchFlag = cli.BoolFlag{
+ Name: "cache.noprefetch",
+ Usage: "Disable heuristic state prefetch during block import (less CPU and disk IO, more time waiting for data)",
+ }
+ // Miner settings
+ MiningEnabledFlag = cli.BoolFlag{
+ Name: "mine",
+ Usage: "Enable mining",
+ }
+ MinerThreadsFlag = cli.IntFlag{
+ Name: "miner.threads",
+ Usage: "Number of CPU threads to use for mining",
+ Value: 0,
+ }
+ MinerLegacyThreadsFlag = cli.IntFlag{
+ Name: "minerthreads",
+ Usage: "Number of CPU threads to use for mining (deprecated, use --miner.threads)",
+ Value: 0,
+ }
+ MinerNotifyFlag = cli.StringFlag{
+ Name: "miner.notify",
+ Usage: "Comma separated HTTP URL list to notify of new work packages",
+ }
+ MinerGasTargetFlag = cli.Uint64Flag{
+ Name: "miner.gastarget",
+ Usage: "Target gas floor for mined blocks",
+ Value: eth.DefaultConfig.MinerGasFloor,
+ }
+ MinerLegacyGasTargetFlag = cli.Uint64Flag{
+ Name: "targetgaslimit",
+ Usage: "Target gas floor for mined blocks (deprecated, use --miner.gastarget)",
+ Value: eth.DefaultConfig.MinerGasFloor,
+ }
+ MinerGasLimitFlag = cli.Uint64Flag{
+ Name: "miner.gaslimit",
+ Usage: "Target gas ceiling for mined blocks",
+ Value: eth.DefaultConfig.MinerGasCeil,
+ }
+ MinerGasPriceFlag = BigFlag{
+ Name: "miner.gasprice",
+ Usage: "Minimum gas price for mining a transaction",
+ Value: eth.DefaultConfig.MinerGasPrice,
+ }
+ MinerLegacyGasPriceFlag = BigFlag{
+ Name: "gasprice",
+ Usage: "Minimum gas price for mining a transaction (deprecated, use --miner.gasprice)",
+ Value: eth.DefaultConfig.MinerGasPrice,
+ }
+ MinerEtherbaseFlag = cli.StringFlag{
+ Name: "miner.etherbase",
+ Usage: "Public address for block mining rewards (default = first account)",
+ Value: "0",
+ }
+ MinerLegacyEtherbaseFlag = cli.StringFlag{
+ Name: "etherbase",
+ Usage: "Public address for block mining rewards (default = first account, deprecated, use --miner.etherbase)",
+ Value: "0",
+ }
+ MinerExtraDataFlag = cli.StringFlag{
+ Name: "miner.extradata",
+ Usage: "Block extra data set by the miner (default = client version)",
+ }
+ MinerLegacyExtraDataFlag = cli.StringFlag{
+ Name: "extradata",
+ Usage: "Block extra data set by the miner (default = client version, deprecated, use --miner.extradata)",
+ }
+ MinerRecommitIntervalFlag = cli.DurationFlag{
+ Name: "miner.recommit",
+ Usage: "Time interval to recreate the block being mined",
+ Value: eth.DefaultConfig.MinerRecommit,
+ }
+ MinerNoVerfiyFlag = cli.BoolFlag{
+ Name: "miner.noverify",
+ Usage: "Disable remote sealing verification",
+ }
+ // Account settings
+ UnlockedAccountFlag = cli.StringFlag{
+ Name: "unlock",
+ Usage: "Comma separated list of accounts to unlock",
+ Value: "",
+ }
+ PasswordFileFlag = cli.StringFlag{
+ Name: "password",
+ Usage: "Password file to use for non-interactive password input",
+ Value: "",
+ }
+ ExternalSignerFlag = cli.StringFlag{
+ Name: "signer",
+ Usage: "External signer (url or path to ipc file)",
+ Value: "",
+ }
+ VMEnableDebugFlag = cli.BoolFlag{
+ Name: "vmdebug",
+ Usage: "Record information useful for VM and contract debugging",
+ }
+ InsecureUnlockAllowedFlag = cli.BoolFlag{
+ Name: "allow-insecure-unlock",
+ Usage: "Allow insecure account unlocking when account-related RPCs are exposed by http",
+ }
+ RPCGlobalGasCap = cli.Uint64Flag{
+ Name: "rpc.gascap",
+ Usage: "Sets a cap on gas that can be used in eth_call/estimateGas",
+ }
+ // Logging and debug settings
+ EthStatsURLFlag = cli.StringFlag{
+ Name: "ethstats",
+ Usage: "Reporting URL of a ethstats service (nodename:secret@host:port)",
+ }
+ FakePoWFlag = cli.BoolFlag{
+ Name: "fakepow",
+ Usage: "Disables proof-of-work verification",
+ }
+ NoCompactionFlag = cli.BoolFlag{
+ Name: "nocompaction",
+ Usage: "Disables db compaction after import",
+ }
+ // RPC settings
+ RPCEnabledFlag = cli.BoolFlag{
+ Name: "rpc",
+ Usage: "Enable the HTTP-RPC server",
+ }
+ RPCListenAddrFlag = cli.StringFlag{
+ Name: "rpcaddr",
+ Usage: "HTTP-RPC server listening interface",
+ Value: node.DefaultHTTPHost,
+ }
+ RPCPortFlag = cli.IntFlag{
+ Name: "rpcport",
+ Usage: "HTTP-RPC server listening port",
+ Value: node.DefaultHTTPPort,
+ }
+ GraphQLEnabledFlag = cli.BoolFlag{
+ Name: "graphql",
+ Usage: "Enable the GraphQL server",
+ }
+ GraphQLListenAddrFlag = cli.StringFlag{
+ Name: "graphql.addr",
+ Usage: "GraphQL server listening interface",
+ Value: node.DefaultGraphQLHost,
+ }
+ GraphQLPortFlag = cli.IntFlag{
+ Name: "graphql.port",
+ Usage: "GraphQL server listening port",
+ Value: node.DefaultGraphQLPort,
+ }
+ GraphQLCORSDomainFlag = cli.StringFlag{
+ Name: "graphql.rpccorsdomain",
+ Usage: "Comma separated list of domains from which to accept cross origin requests (browser enforced)",
+ Value: "",
+ }
+ GraphQLVirtualHostsFlag = cli.StringFlag{
+ Name: "graphql.rpcvhosts",
+ Usage: "Comma separated list of virtual hostnames from which to accept requests (server enforced). Accepts '*' wildcard.",
+ Value: strings.Join(node.DefaultConfig.HTTPVirtualHosts, ","),
+ }
+ RPCCORSDomainFlag = cli.StringFlag{
+ Name: "rpccorsdomain",
+ Usage: "Comma separated list of domains from which to accept cross origin requests (browser enforced)",
+ Value: "",
+ }
+ RPCVirtualHostsFlag = cli.StringFlag{
+ Name: "rpcvhosts",
+ Usage: "Comma separated list of virtual hostnames from which to accept requests (server enforced). Accepts '*' wildcard.",
+ Value: strings.Join(node.DefaultConfig.HTTPVirtualHosts, ","),
+ }
+ RPCApiFlag = cli.StringFlag{
+ Name: "rpcapi",
+ Usage: "API's offered over the HTTP-RPC interface",
+ Value: "",
+ }
+ IPCDisabledFlag = cli.BoolFlag{
+ Name: "ipcdisable",
+ Usage: "Disable the IPC-RPC server",
+ }
+ IPCPathFlag = DirectoryFlag{
+ Name: "ipcpath",
+ Usage: "Filename for IPC socket/pipe within the datadir (explicit paths escape it)",
+ }
+ WSEnabledFlag = cli.BoolFlag{
+ Name: "ws",
+ Usage: "Enable the WS-RPC server",
+ }
+ WSListenAddrFlag = cli.StringFlag{
+ Name: "wsaddr",
+ Usage: "WS-RPC server listening interface",
+ Value: node.DefaultWSHost,
+ }
+ WSPortFlag = cli.IntFlag{
+ Name: "wsport",
+ Usage: "WS-RPC server listening port",
+ Value: node.DefaultWSPort,
+ }
+ WSApiFlag = cli.StringFlag{
+ Name: "wsapi",
+ Usage: "API's offered over the WS-RPC interface",
+ Value: "",
+ }
+ WSAllowedOriginsFlag = cli.StringFlag{
+ Name: "wsorigins",
+ Usage: "Origins from which to accept websockets requests",
+ Value: "",
+ }
+ ExecFlag = cli.StringFlag{
+ Name: "exec",
+ Usage: "Execute JavaScript statement",
+ }
+ PreloadJSFlag = cli.StringFlag{
+ Name: "preload",
+ Usage: "Comma separated list of JavaScript files to preload into the console",
+ }
+
+ // Network Settings
+ MaxPeersFlag = cli.IntFlag{
+ Name: "maxpeers",
+ Usage: "Maximum number of network peers (network disabled if set to 0)",
+ Value: 25,
+ }
+ MaxPendingPeersFlag = cli.IntFlag{
+ Name: "maxpendpeers",
+ Usage: "Maximum number of pending connection attempts (defaults used if set to 0)",
+ Value: 0,
+ }
+ ListenPortFlag = cli.IntFlag{
+ Name: "port",
+ Usage: "Network listening port",
+ Value: 30303,
+ }
+ BootnodesFlag = cli.StringFlag{
+ Name: "bootnodes",
+ Usage: "Comma separated enode URLs for P2P discovery bootstrap (set v4+v5 instead for light servers)",
+ Value: "",
+ }
+ BootnodesV4Flag = cli.StringFlag{
+ Name: "bootnodesv4",
+ Usage: "Comma separated enode URLs for P2P v4 discovery bootstrap (light server, full nodes)",
+ Value: "",
+ }
+ BootnodesV5Flag = cli.StringFlag{
+ Name: "bootnodesv5",
+ Usage: "Comma separated enode URLs for P2P v5 discovery bootstrap (light server, light nodes)",
+ Value: "",
+ }
+ NodeKeyFileFlag = cli.StringFlag{
+ Name: "nodekey",
+ Usage: "P2P node key file",
+ }
+ NodeKeyHexFlag = cli.StringFlag{
+ Name: "nodekeyhex",
+ Usage: "P2P node key as hex (for testing)",
+ }
+ NATFlag = cli.StringFlag{
+ Name: "nat",
+ Usage: "NAT port mapping mechanism (any|none|upnp|pmp|extip:)",
+ Value: "any",
+ }
+ NoDiscoverFlag = cli.BoolFlag{
+ Name: "nodiscover",
+ Usage: "Disables the peer discovery mechanism (manual peer addition)",
+ }
+ DiscoveryV5Flag = cli.BoolFlag{
+ Name: "v5disc",
+ Usage: "Enables the experimental RLPx V5 (Topic Discovery) mechanism",
+ }
+ NetrestrictFlag = cli.StringFlag{
+ Name: "netrestrict",
+ Usage: "Restricts network communication to the given IP networks (CIDR masks)",
+ }
+
+ // ATM the url is left to the user and deployment to
+ JSpathFlag = cli.StringFlag{
+ Name: "jspath",
+ Usage: "JavaScript root path for `loadScript`",
+ Value: ".",
+ }
+
+ // Gas price oracle settings
+ GpoBlocksFlag = cli.IntFlag{
+ Name: "gpoblocks",
+ Usage: "Number of recent blocks to check for gas prices",
+ Value: eth.DefaultConfig.GPO.Blocks,
+ }
+ GpoPercentileFlag = cli.IntFlag{
+ Name: "gpopercentile",
+ Usage: "Suggested gas price is the given percentile of a set of recent transaction gas prices",
+ Value: eth.DefaultConfig.GPO.Percentile,
+ }
+ WhisperEnabledFlag = cli.BoolFlag{
+ Name: "shh",
+ Usage: "Enable Whisper",
+ }
+ WhisperMaxMessageSizeFlag = cli.IntFlag{
+ Name: "shh.maxmessagesize",
+ Usage: "Max message size accepted",
+ Value: int(whisper.DefaultMaxMessageSize),
+ }
+ WhisperMinPOWFlag = cli.Float64Flag{
+ Name: "shh.pow",
+ Usage: "Minimum POW accepted",
+ Value: whisper.DefaultMinimumPoW,
+ }
+ WhisperRestrictConnectionBetweenLightClientsFlag = cli.BoolFlag{
+ Name: "shh.restrict-light",
+ Usage: "Restrict connection between two whisper light clients",
+ }
+
+ // Metrics flags
+ MetricsEnabledFlag = cli.BoolFlag{
+ Name: "metrics",
+ Usage: "Enable metrics collection and reporting",
+ }
+ MetricsEnabledExpensiveFlag = cli.BoolFlag{
+ Name: "metrics.expensive",
+ Usage: "Enable expensive metrics collection and reporting",
+ }
+ MetricsEnableInfluxDBFlag = cli.BoolFlag{
+ Name: "metrics.influxdb",
+ Usage: "Enable metrics export/push to an external InfluxDB database",
+ }
+ MetricsInfluxDBEndpointFlag = cli.StringFlag{
+ Name: "metrics.influxdb.endpoint",
+ Usage: "InfluxDB API endpoint to report metrics to",
+ Value: "http://localhost:8086",
+ }
+ MetricsInfluxDBDatabaseFlag = cli.StringFlag{
+ Name: "metrics.influxdb.database",
+ Usage: "InfluxDB database name to push reported metrics to",
+ Value: "geth",
+ }
+ MetricsInfluxDBUsernameFlag = cli.StringFlag{
+ Name: "metrics.influxdb.username",
+ Usage: "Username to authorize access to the database",
+ Value: "test",
+ }
+ MetricsInfluxDBPasswordFlag = cli.StringFlag{
+ Name: "metrics.influxdb.password",
+ Usage: "Password to authorize access to the database",
+ Value: "test",
+ }
+ // Tags are part of every measurement sent to InfluxDB. Queries on tags are faster in InfluxDB.
+ // For example `host` tag could be used so that we can group all nodes and average a measurement
+ // across all of them, but also so that we can select a specific node and inspect its measurements.
+ // https://docs.influxdata.com/influxdb/v1.4/concepts/key_concepts/#tag-key
+ MetricsInfluxDBTagsFlag = cli.StringFlag{
+ Name: "metrics.influxdb.tags",
+ Usage: "Comma-separated InfluxDB tags (key/values) attached to all measurements",
+ Value: "host=localhost",
+ }
+
+ EWASMInterpreterFlag = cli.StringFlag{
+ Name: "vm.ewasm",
+ Usage: "External ewasm configuration (default = built-in interpreter)",
+ Value: "",
+ }
+ EVMInterpreterFlag = cli.StringFlag{
+ Name: "vm.evm",
+ Usage: "External EVM configuration (default = built-in interpreter)",
+ Value: "",
+ }
+
+ StateDiffFlag = cli.BoolFlag{
+ Name: "statediff",
+ Usage: "Enables the calculation of state diffs between each block, persists these state diffs the configured persistence mode.",
+ }
+)
+
+// MakeDataDir retrieves the currently requested data directory, terminating
+// if none (or the empty string) is specified. If the node is starting a testnet,
+// the a subdirectory of the specified datadir will be used.
+func MakeDataDir(ctx *cli.Context) string {
+ if path := ctx.GlobalString(DataDirFlag.Name); path != "" {
+ if ctx.GlobalBool(TestnetFlag.Name) {
+ return filepath.Join(path, "testnet")
+ }
+ if ctx.GlobalBool(RinkebyFlag.Name) {
+ return filepath.Join(path, "rinkeby")
+ }
+ if ctx.GlobalBool(GoerliFlag.Name) {
+ return filepath.Join(path, "goerli")
+ }
+ return path
+ }
+ Fatalf("Cannot determine default data directory, please set manually (--datadir)")
+ return ""
+}
+
+// setNodeKey creates a node key from set command line flags, either loading it
+// from a file or as a specified hex value. If neither flags were provided, this
+// method returns nil and an emphemeral key is to be generated.
+func setNodeKey(ctx *cli.Context, cfg *p2p.Config) {
+ var (
+ hex = ctx.GlobalString(NodeKeyHexFlag.Name)
+ file = ctx.GlobalString(NodeKeyFileFlag.Name)
+ key *ecdsa.PrivateKey
+ err error
+ )
+ switch {
+ case file != "" && hex != "":
+ Fatalf("Options %q and %q are mutually exclusive", NodeKeyFileFlag.Name, NodeKeyHexFlag.Name)
+ case file != "":
+ if key, err = crypto.LoadECDSA(file); err != nil {
+ Fatalf("Option %q: %v", NodeKeyFileFlag.Name, err)
+ }
+ cfg.PrivateKey = key
+ case hex != "":
+ if key, err = crypto.HexToECDSA(hex); err != nil {
+ Fatalf("Option %q: %v", NodeKeyHexFlag.Name, err)
+ }
+ cfg.PrivateKey = key
+ }
+}
+
+// setNodeUserIdent creates the user identifier from CLI flags.
+func setNodeUserIdent(ctx *cli.Context, cfg *node.Config) {
+ if identity := ctx.GlobalString(IdentityFlag.Name); len(identity) > 0 {
+ cfg.UserIdent = identity
+ }
+}
+
+// setBootstrapNodes creates a list of bootstrap nodes from the command line
+// flags, reverting to pre-configured ones if none have been specified.
+func setBootstrapNodes(ctx *cli.Context, cfg *p2p.Config) {
+ urls := params.MainnetBootnodes
+ switch {
+ case ctx.GlobalIsSet(BootnodesFlag.Name) || ctx.GlobalIsSet(BootnodesV4Flag.Name):
+ if ctx.GlobalIsSet(BootnodesV4Flag.Name) {
+ urls = strings.Split(ctx.GlobalString(BootnodesV4Flag.Name), ",")
+ } else {
+ urls = strings.Split(ctx.GlobalString(BootnodesFlag.Name), ",")
+ }
+ case ctx.GlobalBool(TestnetFlag.Name):
+ urls = params.TestnetBootnodes
+ case ctx.GlobalBool(RinkebyFlag.Name):
+ urls = params.RinkebyBootnodes
+ case ctx.GlobalBool(GoerliFlag.Name):
+ urls = params.GoerliBootnodes
+ case cfg.BootstrapNodes != nil:
+ return // already set, don't apply defaults.
+ }
+
+ cfg.BootstrapNodes = make([]*enode.Node, 0, len(urls))
+ for _, url := range urls {
+ if url != "" {
+ node, err := enode.ParseV4(url)
+ if err != nil {
+ log.Crit("Bootstrap URL invalid", "enode", url, "err", err)
+ continue
+ }
+ cfg.BootstrapNodes = append(cfg.BootstrapNodes, node)
+ }
+ }
+}
+
+// setBootstrapNodesV5 creates a list of bootstrap nodes from the command line
+// flags, reverting to pre-configured ones if none have been specified.
+func setBootstrapNodesV5(ctx *cli.Context, cfg *p2p.Config) {
+ urls := params.DiscoveryV5Bootnodes
+ switch {
+ case ctx.GlobalIsSet(BootnodesFlag.Name) || ctx.GlobalIsSet(BootnodesV5Flag.Name):
+ if ctx.GlobalIsSet(BootnodesV5Flag.Name) {
+ urls = strings.Split(ctx.GlobalString(BootnodesV5Flag.Name), ",")
+ } else {
+ urls = strings.Split(ctx.GlobalString(BootnodesFlag.Name), ",")
+ }
+ case ctx.GlobalBool(RinkebyFlag.Name):
+ urls = params.RinkebyBootnodes
+ case ctx.GlobalBool(GoerliFlag.Name):
+ urls = params.GoerliBootnodes
+ case cfg.BootstrapNodesV5 != nil:
+ return // already set, don't apply defaults.
+ }
+
+ cfg.BootstrapNodesV5 = make([]*discv5.Node, 0, len(urls))
+ for _, url := range urls {
+ if url != "" {
+ node, err := discv5.ParseNode(url)
+ if err != nil {
+ log.Error("Bootstrap URL invalid", "enode", url, "err", err)
+ continue
+ }
+ cfg.BootstrapNodesV5 = append(cfg.BootstrapNodesV5, node)
+ }
+ }
+}
+
+// setListenAddress creates a TCP listening address string from set command
+// line flags.
+func setListenAddress(ctx *cli.Context, cfg *p2p.Config) {
+ if ctx.GlobalIsSet(ListenPortFlag.Name) {
+ cfg.ListenAddr = fmt.Sprintf(":%d", ctx.GlobalInt(ListenPortFlag.Name))
+ }
+}
+
+// setNAT creates a port mapper from command line flags.
+func setNAT(ctx *cli.Context, cfg *p2p.Config) {
+ if ctx.GlobalIsSet(NATFlag.Name) {
+ natif, err := nat.Parse(ctx.GlobalString(NATFlag.Name))
+ if err != nil {
+ Fatalf("Option %s: %v", NATFlag.Name, err)
+ }
+ cfg.NAT = natif
+ }
+}
+
+// splitAndTrim splits input separated by a comma
+// and trims excessive white space from the substrings.
+func splitAndTrim(input string) []string {
+ result := strings.Split(input, ",")
+ for i, r := range result {
+ result[i] = strings.TrimSpace(r)
+ }
+ return result
+}
+
+// setHTTP creates the HTTP RPC listener interface string from the set
+// command line flags, returning empty if the HTTP endpoint is disabled.
+func setHTTP(ctx *cli.Context, cfg *node.Config) {
+ if ctx.GlobalBool(RPCEnabledFlag.Name) && cfg.HTTPHost == "" {
+ cfg.HTTPHost = "127.0.0.1"
+ if ctx.GlobalIsSet(RPCListenAddrFlag.Name) {
+ cfg.HTTPHost = ctx.GlobalString(RPCListenAddrFlag.Name)
+ }
+ }
+
+ if ctx.GlobalIsSet(RPCPortFlag.Name) {
+ cfg.HTTPPort = ctx.GlobalInt(RPCPortFlag.Name)
+ }
+ if ctx.GlobalIsSet(RPCCORSDomainFlag.Name) {
+ cfg.HTTPCors = splitAndTrim(ctx.GlobalString(RPCCORSDomainFlag.Name))
+ }
+ if ctx.GlobalIsSet(RPCApiFlag.Name) {
+ cfg.HTTPModules = splitAndTrim(ctx.GlobalString(RPCApiFlag.Name))
+ }
+ if ctx.GlobalIsSet(RPCVirtualHostsFlag.Name) {
+ cfg.HTTPVirtualHosts = splitAndTrim(ctx.GlobalString(RPCVirtualHostsFlag.Name))
+ }
+}
+
+// setGraphQL creates the GraphQL listener interface string from the set
+// command line flags, returning empty if the GraphQL endpoint is disabled.
+func setGraphQL(ctx *cli.Context, cfg *node.Config) {
+ if ctx.GlobalBool(GraphQLEnabledFlag.Name) && cfg.GraphQLHost == "" {
+ cfg.GraphQLHost = "127.0.0.1"
+ if ctx.GlobalIsSet(GraphQLListenAddrFlag.Name) {
+ cfg.GraphQLHost = ctx.GlobalString(GraphQLListenAddrFlag.Name)
+ }
+ }
+ cfg.GraphQLPort = ctx.GlobalInt(GraphQLPortFlag.Name)
+ if ctx.GlobalIsSet(GraphQLCORSDomainFlag.Name) {
+ cfg.GraphQLCors = splitAndTrim(ctx.GlobalString(GraphQLCORSDomainFlag.Name))
+ }
+ if ctx.GlobalIsSet(GraphQLVirtualHostsFlag.Name) {
+ cfg.GraphQLVirtualHosts = splitAndTrim(ctx.GlobalString(GraphQLVirtualHostsFlag.Name))
+ }
+}
+
+// setWS creates the WebSocket RPC listener interface string from the set
+// command line flags, returning empty if the HTTP endpoint is disabled.
+func setWS(ctx *cli.Context, cfg *node.Config) {
+ if ctx.GlobalBool(WSEnabledFlag.Name) && cfg.WSHost == "" {
+ cfg.WSHost = "127.0.0.1"
+ if ctx.GlobalIsSet(WSListenAddrFlag.Name) {
+ cfg.WSHost = ctx.GlobalString(WSListenAddrFlag.Name)
+ }
+ }
+
+ if ctx.GlobalIsSet(WSPortFlag.Name) {
+ cfg.WSPort = ctx.GlobalInt(WSPortFlag.Name)
+ }
+ if ctx.GlobalIsSet(WSAllowedOriginsFlag.Name) {
+ cfg.WSOrigins = splitAndTrim(ctx.GlobalString(WSAllowedOriginsFlag.Name))
+ }
+ if ctx.GlobalIsSet(WSApiFlag.Name) {
+ cfg.WSModules = splitAndTrim(ctx.GlobalString(WSApiFlag.Name))
+ }
+ if ctx.GlobalBool(StateDiffFlag.Name) {
+ cfg.WSModules = append(cfg.WSModules, "statediff")
+ }
+}
+
+// setIPC creates an IPC path configuration from the set command line flags,
+// returning an empty string if IPC was explicitly disabled, or the set path.
+func setIPC(ctx *cli.Context, cfg *node.Config) {
+ checkExclusive(ctx, IPCDisabledFlag, IPCPathFlag)
+ switch {
+ case ctx.GlobalBool(IPCDisabledFlag.Name):
+ cfg.IPCPath = ""
+ case ctx.GlobalIsSet(IPCPathFlag.Name):
+ cfg.IPCPath = ctx.GlobalString(IPCPathFlag.Name)
+ }
+}
+
+// SetULC setup ULC config from file if given.
+func SetULC(ctx *cli.Context, cfg *eth.Config) {
+ // ULC config isn't loaded from global config and ULC config and ULC trusted nodes are not defined.
+ if cfg.ULC == nil && !(ctx.GlobalIsSet(ULCModeConfigFlag.Name) || ctx.GlobalIsSet(ULCTrustedNodesFlag.Name)) {
+ return
+ }
+ cfg.ULC = ð.ULCConfig{}
+
+ path := ctx.GlobalString(ULCModeConfigFlag.Name)
+ if path != "" {
+ cfgData, err := ioutil.ReadFile(path)
+ if err != nil {
+ Fatalf("Failed to unmarshal ULC configuration: %v", err)
+ }
+
+ err = json.Unmarshal(cfgData, &cfg.ULC)
+ if err != nil {
+ Fatalf("Failed to unmarshal ULC configuration: %s", err.Error())
+ }
+ }
+
+ if trustedNodes := ctx.GlobalString(ULCTrustedNodesFlag.Name); trustedNodes != "" {
+ cfg.ULC.TrustedServers = strings.Split(trustedNodes, ",")
+ }
+
+ if trustedFraction := ctx.GlobalInt(ULCMinTrustedFractionFlag.Name); trustedFraction > 0 {
+ cfg.ULC.MinTrustedFraction = trustedFraction
+ }
+ if cfg.ULC.MinTrustedFraction <= 0 && cfg.ULC.MinTrustedFraction > 100 {
+ log.Error("MinTrustedFraction is invalid", "MinTrustedFraction", cfg.ULC.MinTrustedFraction, "Changed to default", eth.DefaultULCMinTrustedFraction)
+ cfg.ULC.MinTrustedFraction = eth.DefaultULCMinTrustedFraction
+ }
+}
+
+// makeDatabaseHandles raises out the number of allowed file handles per process
+// for Geth and returns half of the allowance to assign to the database.
+func makeDatabaseHandles() int {
+ limit, err := fdlimit.Maximum()
+ if err != nil {
+ Fatalf("Failed to retrieve file descriptor allowance: %v", err)
+ }
+ raised, err := fdlimit.Raise(uint64(limit))
+ if err != nil {
+ Fatalf("Failed to raise file descriptor allowance: %v", err)
+ }
+ return int(raised / 2) // Leave half for networking and other stuff
+}
+
+// MakeAddress converts an account specified directly as a hex encoded string or
+// a key index in the key store to an internal account representation.
+func MakeAddress(ks *keystore.KeyStore, account string) (accounts.Account, error) {
+ // If the specified account is a valid address, return it
+ if common.IsHexAddress(account) {
+ return accounts.Account{Address: common.HexToAddress(account)}, nil
+ }
+ // Otherwise try to interpret the account as a keystore index
+ index, err := strconv.Atoi(account)
+ if err != nil || index < 0 {
+ return accounts.Account{}, fmt.Errorf("invalid account address or index %q", account)
+ }
+ log.Warn("-------------------------------------------------------------------")
+ log.Warn("Referring to accounts by order in the keystore folder is dangerous!")
+ log.Warn("This functionality is deprecated and will be removed in the future!")
+ log.Warn("Please use explicit addresses! (can search via `geth account list`)")
+ log.Warn("-------------------------------------------------------------------")
+
+ accs := ks.Accounts()
+ if len(accs) <= index {
+ return accounts.Account{}, fmt.Errorf("index %d higher than number of accounts %d", index, len(accs))
+ }
+ return accs[index], nil
+}
+
+// setEtherbase retrieves the etherbase either from the directly specified
+// command line flags or from the keystore if CLI indexed.
+func setEtherbase(ctx *cli.Context, ks *keystore.KeyStore, cfg *eth.Config) {
+ // Extract the current etherbase, new flag overriding legacy one
+ var etherbase string
+ if ctx.GlobalIsSet(MinerLegacyEtherbaseFlag.Name) {
+ etherbase = ctx.GlobalString(MinerLegacyEtherbaseFlag.Name)
+ }
+ if ctx.GlobalIsSet(MinerEtherbaseFlag.Name) {
+ etherbase = ctx.GlobalString(MinerEtherbaseFlag.Name)
+ }
+ // Convert the etherbase into an address and configure it
+ if etherbase != "" {
+ if ks != nil {
+ account, err := MakeAddress(ks, etherbase)
+ if err != nil {
+ Fatalf("Invalid miner etherbase: %v", err)
+ }
+ cfg.Etherbase = account.Address
+ } else {
+ Fatalf("No etherbase configured")
+ }
+ }
+}
+
+// MakePasswordList reads password lines from the file specified by the global --password flag.
+func MakePasswordList(ctx *cli.Context) []string {
+ path := ctx.GlobalString(PasswordFileFlag.Name)
+ if path == "" {
+ return nil
+ }
+ text, err := ioutil.ReadFile(path)
+ if err != nil {
+ Fatalf("Failed to read password file: %v", err)
+ }
+ lines := strings.Split(string(text), "\n")
+ // Sanitise DOS line endings.
+ for i := range lines {
+ lines[i] = strings.TrimRight(lines[i], "\r")
+ }
+ return lines
+}
+
+func SetP2PConfig(ctx *cli.Context, cfg *p2p.Config) {
+ setNodeKey(ctx, cfg)
+ setNAT(ctx, cfg)
+ setListenAddress(ctx, cfg)
+ setBootstrapNodes(ctx, cfg)
+ setBootstrapNodesV5(ctx, cfg)
+
+ lightClient := ctx.GlobalString(SyncModeFlag.Name) == "light"
+ lightServer := ctx.GlobalInt(LightServFlag.Name) != 0
+ lightPeers := ctx.GlobalInt(LightPeersFlag.Name)
+
+ if ctx.GlobalIsSet(MaxPeersFlag.Name) {
+ cfg.MaxPeers = ctx.GlobalInt(MaxPeersFlag.Name)
+ if lightServer && !ctx.GlobalIsSet(LightPeersFlag.Name) {
+ cfg.MaxPeers += lightPeers
+ }
+ } else {
+ if lightServer {
+ cfg.MaxPeers += lightPeers
+ }
+ if lightClient && ctx.GlobalIsSet(LightPeersFlag.Name) && cfg.MaxPeers < lightPeers {
+ cfg.MaxPeers = lightPeers
+ }
+ }
+ if !(lightClient || lightServer) {
+ lightPeers = 0
+ }
+ ethPeers := cfg.MaxPeers - lightPeers
+ if lightClient {
+ ethPeers = 0
+ }
+ log.Info("Maximum peer count", "ETH", ethPeers, "LES", lightPeers, "total", cfg.MaxPeers)
+
+ if ctx.GlobalIsSet(MaxPendingPeersFlag.Name) {
+ cfg.MaxPendingPeers = ctx.GlobalInt(MaxPendingPeersFlag.Name)
+ }
+ if ctx.GlobalIsSet(NoDiscoverFlag.Name) || lightClient {
+ cfg.NoDiscovery = true
+ }
+
+ // if we're running a light client or server, force enable the v5 peer discovery
+ // unless it is explicitly disabled with --nodiscover note that explicitly specifying
+ // --v5disc overrides --nodiscover, in which case the later only disables v4 discovery
+ forceV5Discovery := (lightClient || lightServer) && !ctx.GlobalBool(NoDiscoverFlag.Name)
+ if ctx.GlobalIsSet(DiscoveryV5Flag.Name) {
+ cfg.DiscoveryV5 = ctx.GlobalBool(DiscoveryV5Flag.Name)
+ } else if forceV5Discovery {
+ cfg.DiscoveryV5 = true
+ }
+
+ if netrestrict := ctx.GlobalString(NetrestrictFlag.Name); netrestrict != "" {
+ list, err := netutil.ParseNetlist(netrestrict)
+ if err != nil {
+ Fatalf("Option %q: %v", NetrestrictFlag.Name, err)
+ }
+ cfg.NetRestrict = list
+ }
+
+ if ctx.GlobalBool(DeveloperFlag.Name) {
+ // --dev mode can't use p2p networking.
+ cfg.MaxPeers = 0
+ cfg.ListenAddr = ":0"
+ cfg.NoDiscovery = true
+ cfg.DiscoveryV5 = false
+ }
+}
+
+// SetNodeConfig applies node-related command line flags to the config.
+func SetNodeConfig(ctx *cli.Context, cfg *node.Config) {
+ SetP2PConfig(ctx, &cfg.P2P)
+ setIPC(ctx, cfg)
+ setHTTP(ctx, cfg)
+ setGraphQL(ctx, cfg)
+ setWS(ctx, cfg)
+ setNodeUserIdent(ctx, cfg)
+ setDataDir(ctx, cfg)
+
+ if ctx.GlobalIsSet(ExternalSignerFlag.Name) {
+ cfg.ExternalSigner = ctx.GlobalString(ExternalSignerFlag.Name)
+ }
+
+ if ctx.GlobalIsSet(KeyStoreDirFlag.Name) {
+ cfg.KeyStoreDir = ctx.GlobalString(KeyStoreDirFlag.Name)
+ }
+ if ctx.GlobalIsSet(LightKDFFlag.Name) {
+ cfg.UseLightweightKDF = ctx.GlobalBool(LightKDFFlag.Name)
+ }
+ if ctx.GlobalIsSet(NoUSBFlag.Name) {
+ cfg.NoUSB = ctx.GlobalBool(NoUSBFlag.Name)
+ }
+ if ctx.GlobalIsSet(InsecureUnlockAllowedFlag.Name) {
+ cfg.InsecureUnlockAllowed = ctx.GlobalBool(InsecureUnlockAllowedFlag.Name)
+ }
+}
+
+func setDataDir(ctx *cli.Context, cfg *node.Config) {
+ switch {
+ case ctx.GlobalIsSet(DataDirFlag.Name):
+ cfg.DataDir = ctx.GlobalString(DataDirFlag.Name)
+ case ctx.GlobalBool(DeveloperFlag.Name):
+ cfg.DataDir = "" // unless explicitly requested, use memory databases
+ case ctx.GlobalBool(TestnetFlag.Name):
+ cfg.DataDir = filepath.Join(node.DefaultDataDir(), "testnet")
+ case ctx.GlobalBool(RinkebyFlag.Name):
+ cfg.DataDir = filepath.Join(node.DefaultDataDir(), "rinkeby")
+ case ctx.GlobalBool(GoerliFlag.Name):
+ cfg.DataDir = filepath.Join(node.DefaultDataDir(), "goerli")
+ }
+}
+
+func setGPO(ctx *cli.Context, cfg *gasprice.Config) {
+ if ctx.GlobalIsSet(GpoBlocksFlag.Name) {
+ cfg.Blocks = ctx.GlobalInt(GpoBlocksFlag.Name)
+ }
+ if ctx.GlobalIsSet(GpoPercentileFlag.Name) {
+ cfg.Percentile = ctx.GlobalInt(GpoPercentileFlag.Name)
+ }
+}
+
+func setTxPool(ctx *cli.Context, cfg *core.TxPoolConfig) {
+ if ctx.GlobalIsSet(TxPoolLocalsFlag.Name) {
+ locals := strings.Split(ctx.GlobalString(TxPoolLocalsFlag.Name), ",")
+ for _, account := range locals {
+ if trimmed := strings.TrimSpace(account); !common.IsHexAddress(trimmed) {
+ Fatalf("Invalid account in --txpool.locals: %s", trimmed)
+ } else {
+ cfg.Locals = append(cfg.Locals, common.HexToAddress(account))
+ }
+ }
+ }
+ if ctx.GlobalIsSet(TxPoolNoLocalsFlag.Name) {
+ cfg.NoLocals = ctx.GlobalBool(TxPoolNoLocalsFlag.Name)
+ }
+ if ctx.GlobalIsSet(TxPoolJournalFlag.Name) {
+ cfg.Journal = ctx.GlobalString(TxPoolJournalFlag.Name)
+ }
+ if ctx.GlobalIsSet(TxPoolRejournalFlag.Name) {
+ cfg.Rejournal = ctx.GlobalDuration(TxPoolRejournalFlag.Name)
+ }
+ if ctx.GlobalIsSet(TxPoolPriceLimitFlag.Name) {
+ cfg.PriceLimit = ctx.GlobalUint64(TxPoolPriceLimitFlag.Name)
+ }
+ if ctx.GlobalIsSet(TxPoolPriceBumpFlag.Name) {
+ cfg.PriceBump = ctx.GlobalUint64(TxPoolPriceBumpFlag.Name)
+ }
+ if ctx.GlobalIsSet(TxPoolAccountSlotsFlag.Name) {
+ cfg.AccountSlots = ctx.GlobalUint64(TxPoolAccountSlotsFlag.Name)
+ }
+ if ctx.GlobalIsSet(TxPoolGlobalSlotsFlag.Name) {
+ cfg.GlobalSlots = ctx.GlobalUint64(TxPoolGlobalSlotsFlag.Name)
+ }
+ if ctx.GlobalIsSet(TxPoolAccountQueueFlag.Name) {
+ cfg.AccountQueue = ctx.GlobalUint64(TxPoolAccountQueueFlag.Name)
+ }
+ if ctx.GlobalIsSet(TxPoolGlobalQueueFlag.Name) {
+ cfg.GlobalQueue = ctx.GlobalUint64(TxPoolGlobalQueueFlag.Name)
+ }
+ if ctx.GlobalIsSet(TxPoolLifetimeFlag.Name) {
+ cfg.Lifetime = ctx.GlobalDuration(TxPoolLifetimeFlag.Name)
+ }
+}
+
+func setEthash(ctx *cli.Context, cfg *eth.Config) {
+ if ctx.GlobalIsSet(EthashCacheDirFlag.Name) {
+ cfg.Ethash.CacheDir = ctx.GlobalString(EthashCacheDirFlag.Name)
+ }
+ if ctx.GlobalIsSet(EthashDatasetDirFlag.Name) {
+ cfg.Ethash.DatasetDir = ctx.GlobalString(EthashDatasetDirFlag.Name)
+ }
+ if ctx.GlobalIsSet(EthashCachesInMemoryFlag.Name) {
+ cfg.Ethash.CachesInMem = ctx.GlobalInt(EthashCachesInMemoryFlag.Name)
+ }
+ if ctx.GlobalIsSet(EthashCachesOnDiskFlag.Name) {
+ cfg.Ethash.CachesOnDisk = ctx.GlobalInt(EthashCachesOnDiskFlag.Name)
+ }
+ if ctx.GlobalIsSet(EthashDatasetsInMemoryFlag.Name) {
+ cfg.Ethash.DatasetsInMem = ctx.GlobalInt(EthashDatasetsInMemoryFlag.Name)
+ }
+ if ctx.GlobalIsSet(EthashDatasetsOnDiskFlag.Name) {
+ cfg.Ethash.DatasetsOnDisk = ctx.GlobalInt(EthashDatasetsOnDiskFlag.Name)
+ }
+}
+
+func setWhitelist(ctx *cli.Context, cfg *eth.Config) {
+ whitelist := ctx.GlobalString(WhitelistFlag.Name)
+ if whitelist == "" {
+ return
+ }
+ cfg.Whitelist = make(map[uint64]common.Hash)
+ for _, entry := range strings.Split(whitelist, ",") {
+ parts := strings.Split(entry, "=")
+ if len(parts) != 2 {
+ Fatalf("Invalid whitelist entry: %s", entry)
+ }
+ number, err := strconv.ParseUint(parts[0], 0, 64)
+ if err != nil {
+ Fatalf("Invalid whitelist block number %s: %v", parts[0], err)
+ }
+ var hash common.Hash
+ if err = hash.UnmarshalText([]byte(parts[1])); err != nil {
+ Fatalf("Invalid whitelist hash %s: %v", parts[1], err)
+ }
+ cfg.Whitelist[number] = hash
+ }
+}
+
+// checkExclusive verifies that only a single instance of the provided flags was
+// set by the user. Each flag might optionally be followed by a string type to
+// specialize it further.
+func checkExclusive(ctx *cli.Context, args ...interface{}) {
+ set := make([]string, 0, 1)
+ for i := 0; i < len(args); i++ {
+ // Make sure the next argument is a flag and skip if not set
+ flag, ok := args[i].(cli.Flag)
+ if !ok {
+ panic(fmt.Sprintf("invalid argument, not cli.Flag type: %T", args[i]))
+ }
+ // Check if next arg extends current and expand its name if so
+ name := flag.GetName()
+
+ if i+1 < len(args) {
+ switch option := args[i+1].(type) {
+ case string:
+ // Extended flag check, make sure value set doesn't conflict with passed in option
+ if ctx.GlobalString(flag.GetName()) == option {
+ name += "=" + option
+ set = append(set, "--"+name)
+ }
+ // shift arguments and continue
+ i++
+ continue
+
+ case cli.Flag:
+ default:
+ panic(fmt.Sprintf("invalid argument, not cli.Flag or string extension: %T", args[i+1]))
+ }
+ }
+ // Mark the flag if it's set
+ if ctx.GlobalIsSet(flag.GetName()) {
+ set = append(set, "--"+name)
+ }
+ }
+ if len(set) > 1 {
+ Fatalf("Flags %v can't be used at the same time", strings.Join(set, ", "))
+ }
+}
+
+// SetShhConfig applies shh-related command line flags to the config.
+func SetShhConfig(ctx *cli.Context, stack *node.Node, cfg *whisper.Config) {
+ if ctx.GlobalIsSet(WhisperMaxMessageSizeFlag.Name) {
+ cfg.MaxMessageSize = uint32(ctx.GlobalUint(WhisperMaxMessageSizeFlag.Name))
+ }
+ if ctx.GlobalIsSet(WhisperMinPOWFlag.Name) {
+ cfg.MinimumAcceptedPOW = ctx.GlobalFloat64(WhisperMinPOWFlag.Name)
+ }
+ if ctx.GlobalIsSet(WhisperRestrictConnectionBetweenLightClientsFlag.Name) {
+ cfg.RestrictConnectionBetweenLightClients = true
+ }
+}
+
+// SetEthConfig applies eth-related command line flags to the config.
+func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *eth.Config) {
+ // Avoid conflicting network flags
+ checkExclusive(ctx, DeveloperFlag, TestnetFlag, RinkebyFlag, GoerliFlag)
+ checkExclusive(ctx, LightServFlag, SyncModeFlag, "light")
+ // Can't use both ephemeral unlocked and external signer
+ checkExclusive(ctx, DeveloperFlag, ExternalSignerFlag)
+ var ks *keystore.KeyStore
+ if keystores := stack.AccountManager().Backends(keystore.KeyStoreType); len(keystores) > 0 {
+ ks = keystores[0].(*keystore.KeyStore)
+ }
+ setEtherbase(ctx, ks, cfg)
+ setGPO(ctx, &cfg.GPO)
+ setTxPool(ctx, &cfg.TxPool)
+ setEthash(ctx, cfg)
+ setWhitelist(ctx, cfg)
+
+ if ctx.GlobalIsSet(SyncModeFlag.Name) {
+ cfg.SyncMode = *GlobalTextMarshaler(ctx, SyncModeFlag.Name).(*downloader.SyncMode)
+ }
+ if ctx.GlobalIsSet(LightServFlag.Name) {
+ cfg.LightServ = ctx.GlobalInt(LightServFlag.Name)
+ }
+ cfg.LightBandwidthIn = ctx.GlobalInt(LightBandwidthInFlag.Name)
+ cfg.LightBandwidthOut = ctx.GlobalInt(LightBandwidthOutFlag.Name)
+ if ctx.GlobalIsSet(LightPeersFlag.Name) {
+ cfg.LightPeers = ctx.GlobalInt(LightPeersFlag.Name)
+ }
+ if ctx.GlobalIsSet(OnlyAnnounceModeFlag.Name) {
+ cfg.OnlyAnnounce = ctx.GlobalBool(OnlyAnnounceModeFlag.Name)
+ }
+ if ctx.GlobalIsSet(NetworkIdFlag.Name) {
+ cfg.NetworkId = ctx.GlobalUint64(NetworkIdFlag.Name)
+ }
+ if ctx.GlobalIsSet(CacheFlag.Name) || ctx.GlobalIsSet(CacheDatabaseFlag.Name) {
+ cfg.DatabaseCache = ctx.GlobalInt(CacheFlag.Name) * ctx.GlobalInt(CacheDatabaseFlag.Name) / 100
+ }
+ cfg.DatabaseHandles = makeDatabaseHandles()
+
+ if gcmode := ctx.GlobalString(GCModeFlag.Name); gcmode != "full" && gcmode != "archive" {
+ Fatalf("--%s must be either 'full' or 'archive'", GCModeFlag.Name)
+ }
+ cfg.NoPruning = ctx.GlobalString(GCModeFlag.Name) == "archive"
+ cfg.NoPrefetch = ctx.GlobalBool(CacheNoPrefetchFlag.Name)
+
+ if ctx.GlobalIsSet(CacheFlag.Name) || ctx.GlobalIsSet(CacheTrieFlag.Name) {
+ cfg.TrieCleanCache = ctx.GlobalInt(CacheFlag.Name) * ctx.GlobalInt(CacheTrieFlag.Name) / 100
+ }
+ if ctx.GlobalIsSet(CacheFlag.Name) || ctx.GlobalIsSet(CacheGCFlag.Name) {
+ cfg.TrieDirtyCache = ctx.GlobalInt(CacheFlag.Name) * ctx.GlobalInt(CacheGCFlag.Name) / 100
+ }
+ if ctx.GlobalIsSet(MinerNotifyFlag.Name) {
+ cfg.MinerNotify = strings.Split(ctx.GlobalString(MinerNotifyFlag.Name), ",")
+ }
+ if ctx.GlobalIsSet(DocRootFlag.Name) {
+ cfg.DocRoot = ctx.GlobalString(DocRootFlag.Name)
+ }
+ if ctx.GlobalIsSet(MinerLegacyExtraDataFlag.Name) {
+ cfg.MinerExtraData = []byte(ctx.GlobalString(MinerLegacyExtraDataFlag.Name))
+ }
+ if ctx.GlobalIsSet(MinerExtraDataFlag.Name) {
+ cfg.MinerExtraData = []byte(ctx.GlobalString(MinerExtraDataFlag.Name))
+ }
+ if ctx.GlobalIsSet(MinerLegacyGasTargetFlag.Name) {
+ cfg.MinerGasFloor = ctx.GlobalUint64(MinerLegacyGasTargetFlag.Name)
+ }
+ if ctx.GlobalIsSet(MinerGasTargetFlag.Name) {
+ cfg.MinerGasFloor = ctx.GlobalUint64(MinerGasTargetFlag.Name)
+ }
+ if ctx.GlobalIsSet(MinerGasLimitFlag.Name) {
+ cfg.MinerGasCeil = ctx.GlobalUint64(MinerGasLimitFlag.Name)
+ }
+ if ctx.GlobalIsSet(MinerLegacyGasPriceFlag.Name) {
+ cfg.MinerGasPrice = GlobalBig(ctx, MinerLegacyGasPriceFlag.Name)
+ }
+ if ctx.GlobalIsSet(MinerGasPriceFlag.Name) {
+ cfg.MinerGasPrice = GlobalBig(ctx, MinerGasPriceFlag.Name)
+ }
+ if ctx.GlobalIsSet(MinerRecommitIntervalFlag.Name) {
+ cfg.MinerRecommit = ctx.Duration(MinerRecommitIntervalFlag.Name)
+ }
+ if ctx.GlobalIsSet(MinerNoVerfiyFlag.Name) {
+ cfg.MinerNoverify = ctx.Bool(MinerNoVerfiyFlag.Name)
+ }
+ if ctx.GlobalIsSet(VMEnableDebugFlag.Name) {
+ // TODO(fjl): force-enable this in --dev mode
+ cfg.EnablePreimageRecording = ctx.GlobalBool(VMEnableDebugFlag.Name)
+ }
+
+ if ctx.GlobalIsSet(EWASMInterpreterFlag.Name) {
+ cfg.EWASMInterpreter = ctx.GlobalString(EWASMInterpreterFlag.Name)
+ }
+
+ if ctx.GlobalIsSet(EVMInterpreterFlag.Name) {
+ cfg.EVMInterpreter = ctx.GlobalString(EVMInterpreterFlag.Name)
+ }
+ if ctx.GlobalIsSet(RPCGlobalGasCap.Name) {
+ cfg.RPCGasCap = new(big.Int).SetUint64(ctx.GlobalUint64(RPCGlobalGasCap.Name))
+ }
+
+ // Override any default configs for hard coded networks.
+ switch {
+ case ctx.GlobalBool(TestnetFlag.Name):
+ if !ctx.GlobalIsSet(NetworkIdFlag.Name) {
+ cfg.NetworkId = 3
+ }
+ cfg.Genesis = core.DefaultTestnetGenesisBlock()
+ case ctx.GlobalBool(RinkebyFlag.Name):
+ if !ctx.GlobalIsSet(NetworkIdFlag.Name) {
+ cfg.NetworkId = 4
+ }
+ cfg.Genesis = core.DefaultRinkebyGenesisBlock()
+ case ctx.GlobalBool(GoerliFlag.Name):
+ if !ctx.GlobalIsSet(NetworkIdFlag.Name) {
+ cfg.NetworkId = 5
+ }
+ cfg.Genesis = core.DefaultGoerliGenesisBlock()
+ case ctx.GlobalBool(DeveloperFlag.Name):
+ if !ctx.GlobalIsSet(NetworkIdFlag.Name) {
+ cfg.NetworkId = 1337
+ }
+ // Create new developer account or reuse existing one
+ var (
+ developer accounts.Account
+ err error
+ )
+ if accs := ks.Accounts(); len(accs) > 0 {
+ developer = ks.Accounts()[0]
+ } else {
+ developer, err = ks.NewAccount("")
+ if err != nil {
+ Fatalf("Failed to create developer account: %v", err)
+ }
+ }
+ if err := ks.Unlock(developer, ""); err != nil {
+ Fatalf("Failed to unlock developer account: %v", err)
+ }
+ log.Info("Using developer account", "address", developer.Address)
+
+ cfg.Genesis = core.DeveloperGenesisBlock(uint64(ctx.GlobalInt(DeveloperPeriodFlag.Name)), developer.Address)
+ if !ctx.GlobalIsSet(MinerGasPriceFlag.Name) && !ctx.GlobalIsSet(MinerLegacyGasPriceFlag.Name) {
+ cfg.MinerGasPrice = big.NewInt(1)
+ }
+ }
+}
+
+// SetDashboardConfig applies dashboard related command line flags to the config.
+func SetDashboardConfig(ctx *cli.Context, cfg *dashboard.Config) {
+ cfg.Host = ctx.GlobalString(DashboardAddrFlag.Name)
+ cfg.Port = ctx.GlobalInt(DashboardPortFlag.Name)
+ cfg.Refresh = ctx.GlobalDuration(DashboardRefreshFlag.Name)
+}
+
+// RegisterEthService adds an Ethereum client to the stack.
+func RegisterEthService(stack *node.Node, cfg *eth.Config) {
+ var err error
+ if cfg.SyncMode == downloader.LightSync {
+ err = stack.Register(func(ctx *node.ServiceContext) (node.Service, error) {
+ return les.New(ctx, cfg)
+ })
+ } else {
+ err = stack.Register(func(ctx *node.ServiceContext) (node.Service, error) {
+ fullNode, err := eth.New(ctx, cfg)
+ if fullNode != nil && cfg.LightServ > 0 {
+ ls, _ := les.NewLesServer(fullNode, cfg)
+ fullNode.AddLesServer(ls)
+ }
+ return fullNode, err
+ })
+ }
+ if err != nil {
+ Fatalf("Failed to register the Ethereum service: %v", err)
+ }
+}
+
+// RegisterDashboardService adds a dashboard to the stack.
+func RegisterDashboardService(stack *node.Node, cfg *dashboard.Config, commit string) {
+ stack.Register(func(ctx *node.ServiceContext) (node.Service, error) {
+ return dashboard.New(cfg, commit, ctx.ResolvePath("logs")), nil
+ })
+}
+
+// RegisterShhService configures Whisper and adds it to the given node.
+func RegisterShhService(stack *node.Node, cfg *whisper.Config) {
+ if err := stack.Register(func(n *node.ServiceContext) (node.Service, error) {
+ return whisper.New(cfg), nil
+ }); err != nil {
+ Fatalf("Failed to register the Whisper service: %v", err)
+ }
+}
+
+// RegisterEthStatsService configures the Ethereum Stats daemon and adds it to
+// the given node.
+func RegisterEthStatsService(stack *node.Node, url string) {
+ if err := stack.Register(func(ctx *node.ServiceContext) (node.Service, error) {
+ // Retrieve both eth and les services
+ var ethServ *eth.Ethereum
+ ctx.Service(ðServ)
+
+ var lesServ *les.LightEthereum
+ ctx.Service(&lesServ)
+
+ return ethstats.New(url, ethServ, lesServ)
+ }); err != nil {
+ Fatalf("Failed to register the Ethereum Stats service: %v", err)
+ }
+}
+
+// RegisterStateDiffService configures and registers a service to stream state diff data over RPC
+func RegisterStateDiffService(stack *node.Node, ctx *cli.Context) {
+ if err := stack.Register(func(ctx *node.ServiceContext) (node.Service, error) {
+ var ethServ *eth.Ethereum
+ ctx.Service(ðServ)
+ chainDb := ethServ.ChainDb()
+ blockChain := ethServ.BlockChain()
+ return statediff.NewStateDiffService(chainDb, blockChain)
+ }); err != nil {
+ Fatalf("Failed to register State Diff Service", err)
+ }
+}
+
+func SetupMetrics(ctx *cli.Context) {
+ if metrics.Enabled {
+ log.Info("Enabling metrics collection")
+ var (
+ enableExport = ctx.GlobalBool(MetricsEnableInfluxDBFlag.Name)
+ endpoint = ctx.GlobalString(MetricsInfluxDBEndpointFlag.Name)
+ database = ctx.GlobalString(MetricsInfluxDBDatabaseFlag.Name)
+ username = ctx.GlobalString(MetricsInfluxDBUsernameFlag.Name)
+ password = ctx.GlobalString(MetricsInfluxDBPasswordFlag.Name)
+ )
+
+ if enableExport {
+ tagsMap := SplitTagsFlag(ctx.GlobalString(MetricsInfluxDBTagsFlag.Name))
+
+ log.Info("Enabling metrics export to InfluxDB")
+
+ go influxdb.InfluxDBWithTags(metrics.DefaultRegistry, 10*time.Second, endpoint, database, username, password, "geth.", tagsMap)
+ }
+ }
+}
+
+func SplitTagsFlag(tagsFlag string) map[string]string {
+ tags := strings.Split(tagsFlag, ",")
+ tagsMap := map[string]string{}
+
+ for _, t := range tags {
+ if t != "" {
+ kv := strings.Split(t, "=")
+
+ if len(kv) == 2 {
+ tagsMap[kv[0]] = kv[1]
+ }
+ }
+ }
+
+ return tagsMap
+}
+
+// MakeChainDatabase open an LevelDB using the flags passed to the client and will hard crash if it fails.
+func MakeChainDatabase(ctx *cli.Context, stack *node.Node) ethdb.Database {
+ var (
+ cache = ctx.GlobalInt(CacheFlag.Name) * ctx.GlobalInt(CacheDatabaseFlag.Name) / 100
+ handles = makeDatabaseHandles()
+ )
+ name := "chaindata"
+ if ctx.GlobalString(SyncModeFlag.Name) == "light" {
+ name = "lightchaindata"
+ }
+ chainDb, err := stack.OpenDatabase(name, cache, handles, "")
+ if err != nil {
+ Fatalf("Could not open database: %v", err)
+ }
+ return chainDb
+}
+
+func MakeGenesis(ctx *cli.Context) *core.Genesis {
+ var genesis *core.Genesis
+ switch {
+ case ctx.GlobalBool(TestnetFlag.Name):
+ genesis = core.DefaultTestnetGenesisBlock()
+ case ctx.GlobalBool(RinkebyFlag.Name):
+ genesis = core.DefaultRinkebyGenesisBlock()
+ case ctx.GlobalBool(GoerliFlag.Name):
+ genesis = core.DefaultGoerliGenesisBlock()
+ case ctx.GlobalBool(DeveloperFlag.Name):
+ Fatalf("Developer chains are ephemeral")
+ }
+ return genesis
+}
+
+// MakeChain creates a chain manager from set command line flags.
+func MakeChain(ctx *cli.Context, stack *node.Node) (chain *core.BlockChain, chainDb ethdb.Database) {
+ var err error
+ chainDb = MakeChainDatabase(ctx, stack)
+ config, _, err := core.SetupGenesisBlock(chainDb, MakeGenesis(ctx))
+ if err != nil {
+ Fatalf("%v", err)
+ }
+ var engine consensus.Engine
+ if config.Clique != nil {
+ engine = clique.New(config.Clique, chainDb)
+ } else {
+ engine = ethash.NewFaker()
+ if !ctx.GlobalBool(FakePoWFlag.Name) {
+ engine = ethash.New(ethash.Config{
+ CacheDir: stack.ResolvePath(eth.DefaultConfig.Ethash.CacheDir),
+ CachesInMem: eth.DefaultConfig.Ethash.CachesInMem,
+ CachesOnDisk: eth.DefaultConfig.Ethash.CachesOnDisk,
+ DatasetDir: stack.ResolvePath(eth.DefaultConfig.Ethash.DatasetDir),
+ DatasetsInMem: eth.DefaultConfig.Ethash.DatasetsInMem,
+ DatasetsOnDisk: eth.DefaultConfig.Ethash.DatasetsOnDisk,
+ }, nil, false)
+ }
+ }
+ if gcmode := ctx.GlobalString(GCModeFlag.Name); gcmode != "full" && gcmode != "archive" {
+ Fatalf("--%s must be either 'full' or 'archive'", GCModeFlag.Name)
+ }
+ cache := &core.CacheConfig{
+ TrieCleanLimit: eth.DefaultConfig.TrieCleanCache,
+ TrieCleanNoPrefetch: ctx.GlobalBool(CacheNoPrefetchFlag.Name),
+ TrieDirtyLimit: eth.DefaultConfig.TrieDirtyCache,
+ TrieDirtyDisabled: ctx.GlobalString(GCModeFlag.Name) == "archive",
+ TrieTimeLimit: eth.DefaultConfig.TrieTimeout,
+ }
+ if ctx.GlobalIsSet(CacheFlag.Name) || ctx.GlobalIsSet(CacheTrieFlag.Name) {
+ cache.TrieCleanLimit = ctx.GlobalInt(CacheFlag.Name) * ctx.GlobalInt(CacheTrieFlag.Name) / 100
+ }
+ if ctx.GlobalIsSet(CacheFlag.Name) || ctx.GlobalIsSet(CacheGCFlag.Name) {
+ cache.TrieDirtyLimit = ctx.GlobalInt(CacheFlag.Name) * ctx.GlobalInt(CacheGCFlag.Name) / 100
+ }
+ vmcfg := vm.Config{EnablePreimageRecording: ctx.GlobalBool(VMEnableDebugFlag.Name)}
+ chain, err = core.NewBlockChain(chainDb, cache, config, engine, vmcfg, nil)
+ if err != nil {
+ Fatalf("Can't create BlockChain: %v", err)
+ }
+ return chain, chainDb
+}
+
+// MakeConsolePreloads retrieves the absolute paths for the console JavaScript
+// scripts to preload before starting.
+func MakeConsolePreloads(ctx *cli.Context) []string {
+ // Skip preloading if there's nothing to preload
+ if ctx.GlobalString(PreloadJSFlag.Name) == "" {
+ return nil
+ }
+ // Otherwise resolve absolute paths and return them
+ var preloads []string
+
+ assets := ctx.GlobalString(JSpathFlag.Name)
+ for _, file := range strings.Split(ctx.GlobalString(PreloadJSFlag.Name), ",") {
+ preloads = append(preloads, common.AbsolutePath(assets, strings.TrimSpace(file)))
+ }
+ return preloads
+}
+
+// MigrateFlags sets the global flag from a local flag when it's set.
+// This is a temporary function used for migrating old command/flags to the
+// new format.
+//
+// e.g. geth account new --keystore /tmp/mykeystore --lightkdf
+//
+// is equivalent after calling this method with:
+//
+// geth --keystore /tmp/mykeystore --lightkdf account new
+//
+// This allows the use of the existing configuration functionality.
+// When all flags are migrated this function can be removed and the existing
+// configuration functionality must be changed that is uses local flags
+func MigrateFlags(action func(ctx *cli.Context) error) func(*cli.Context) error {
+ return func(ctx *cli.Context) error {
+ for _, name := range ctx.FlagNames() {
+ if ctx.IsSet(name) {
+ ctx.GlobalSet(name, ctx.String(name))
+ }
+ }
+ return action(ctx)
+ }
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/cmd/wnode/main.go b/vendor/github.com/ethereum/go-ethereum/cmd/wnode/main.go
new file mode 100644
index 00000000..97e58520
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/cmd/wnode/main.go
@@ -0,0 +1,772 @@
+// Copyright 2017 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// go-ethereum is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with go-ethereum. If not, see .
+
+// This is a simple Whisper node. It could be used as a stand-alone bootstrap node.
+// Also, could be used for different test and diagnostics purposes.
+
+package main
+
+import (
+ "bufio"
+ "crypto/ecdsa"
+ crand "crypto/rand"
+ "crypto/sha512"
+ "encoding/binary"
+ "encoding/hex"
+ "flag"
+ "fmt"
+ "io/ioutil"
+ "os"
+ "path/filepath"
+ "strconv"
+ "strings"
+ "time"
+
+ "github.com/ethereum/go-ethereum/cmd/utils"
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/console"
+ "github.com/ethereum/go-ethereum/crypto"
+ "github.com/ethereum/go-ethereum/log"
+ "github.com/ethereum/go-ethereum/p2p"
+ "github.com/ethereum/go-ethereum/p2p/enode"
+ "github.com/ethereum/go-ethereum/p2p/nat"
+ "github.com/ethereum/go-ethereum/whisper/mailserver"
+ whisper "github.com/ethereum/go-ethereum/whisper/whisperv6"
+ "golang.org/x/crypto/pbkdf2"
+)
+
+const quitCommand = "~Q"
+const entropySize = 32
+
+// singletons
+var (
+ server *p2p.Server
+ shh *whisper.Whisper
+ done chan struct{}
+ mailServer mailserver.WMailServer
+ entropy [entropySize]byte
+
+ input = bufio.NewReader(os.Stdin)
+)
+
+// encryption
+var (
+ symKey []byte
+ pub *ecdsa.PublicKey
+ asymKey *ecdsa.PrivateKey
+ nodeid *ecdsa.PrivateKey
+ topic whisper.TopicType
+
+ asymKeyID string
+ asymFilterID string
+ symFilterID string
+ symPass string
+ msPassword string
+)
+
+// cmd arguments
+var (
+ bootstrapMode = flag.Bool("standalone", false, "boostrap node: don't initiate connection to peers, just wait for incoming connections")
+ forwarderMode = flag.Bool("forwarder", false, "forwarder mode: only forward messages, neither encrypt nor decrypt messages")
+ mailServerMode = flag.Bool("mailserver", false, "mail server mode: delivers expired messages on demand")
+ requestMail = flag.Bool("mailclient", false, "request expired messages from the bootstrap server")
+ asymmetricMode = flag.Bool("asym", false, "use asymmetric encryption")
+ generateKey = flag.Bool("generatekey", false, "generate and show the private key")
+ fileExMode = flag.Bool("fileexchange", false, "file exchange mode")
+ fileReader = flag.Bool("filereader", false, "load and decrypt messages saved as files, display as plain text")
+ testMode = flag.Bool("test", false, "use of predefined parameters for diagnostics (password, etc.)")
+ echoMode = flag.Bool("echo", false, "echo mode: prints some arguments for diagnostics")
+
+ argVerbosity = flag.Int("verbosity", int(log.LvlError), "log verbosity level")
+ argTTL = flag.Uint("ttl", 30, "time-to-live for messages in seconds")
+ argWorkTime = flag.Uint("work", 5, "work time in seconds")
+ argMaxSize = flag.Uint("maxsize", uint(whisper.DefaultMaxMessageSize), "max size of message")
+ argPoW = flag.Float64("pow", whisper.DefaultMinimumPoW, "PoW for normal messages in float format (e.g. 2.7)")
+ argServerPoW = flag.Float64("mspow", whisper.DefaultMinimumPoW, "PoW requirement for Mail Server request")
+
+ argIP = flag.String("ip", "", "IP address and port of this node (e.g. 127.0.0.1:30303)")
+ argPub = flag.String("pub", "", "public key for asymmetric encryption")
+ argDBPath = flag.String("dbpath", "", "path to the server's DB directory")
+ argIDFile = flag.String("idfile", "", "file name with node id (private key)")
+ argEnode = flag.String("boot", "", "bootstrap node you want to connect to (e.g. enode://e454......08d50@52.176.211.200:16428)")
+ argTopic = flag.String("topic", "", "topic in hexadecimal format (e.g. 70a4beef)")
+ argSaveDir = flag.String("savedir", "", "directory where all incoming messages will be saved as files")
+)
+
+func main() {
+ processArgs()
+ initialize()
+ run()
+ shutdown()
+}
+
+func processArgs() {
+ flag.Parse()
+
+ if len(*argIDFile) > 0 {
+ var err error
+ nodeid, err = crypto.LoadECDSA(*argIDFile)
+ if err != nil {
+ utils.Fatalf("Failed to load file [%s]: %s.", *argIDFile, err)
+ }
+ }
+
+ const enodePrefix = "enode://"
+ if len(*argEnode) > 0 {
+ if (*argEnode)[:len(enodePrefix)] != enodePrefix {
+ *argEnode = enodePrefix + *argEnode
+ }
+ }
+
+ if len(*argTopic) > 0 {
+ x, err := hex.DecodeString(*argTopic)
+ if err != nil {
+ utils.Fatalf("Failed to parse the topic: %s", err)
+ }
+ topic = whisper.BytesToTopic(x)
+ }
+
+ if *asymmetricMode && len(*argPub) > 0 {
+ var err error
+ if pub, err = crypto.UnmarshalPubkey(common.FromHex(*argPub)); err != nil {
+ utils.Fatalf("invalid public key")
+ }
+ }
+
+ if len(*argSaveDir) > 0 {
+ if _, err := os.Stat(*argSaveDir); os.IsNotExist(err) {
+ utils.Fatalf("Download directory '%s' does not exist", *argSaveDir)
+ }
+ } else if *fileExMode {
+ utils.Fatalf("Parameter 'savedir' is mandatory for file exchange mode")
+ }
+
+ if *echoMode {
+ echo()
+ }
+}
+
+func echo() {
+ fmt.Printf("ttl = %d \n", *argTTL)
+ fmt.Printf("workTime = %d \n", *argWorkTime)
+ fmt.Printf("pow = %f \n", *argPoW)
+ fmt.Printf("mspow = %f \n", *argServerPoW)
+ fmt.Printf("ip = %s \n", *argIP)
+ fmt.Printf("pub = %s \n", common.ToHex(crypto.FromECDSAPub(pub)))
+ fmt.Printf("idfile = %s \n", *argIDFile)
+ fmt.Printf("dbpath = %s \n", *argDBPath)
+ fmt.Printf("boot = %s \n", *argEnode)
+}
+
+func initialize() {
+ log.Root().SetHandler(log.LvlFilterHandler(log.Lvl(*argVerbosity), log.StreamHandler(os.Stderr, log.TerminalFormat(false))))
+
+ done = make(chan struct{})
+ var peers []*enode.Node
+ var err error
+
+ if *generateKey {
+ key, err := crypto.GenerateKey()
+ if err != nil {
+ utils.Fatalf("Failed to generate private key: %s", err)
+ }
+ k := hex.EncodeToString(crypto.FromECDSA(key))
+ fmt.Printf("Random private key: %s \n", k)
+ os.Exit(0)
+ }
+
+ if *testMode {
+ symPass = "wwww" // ascii code: 0x77777777
+ msPassword = "wwww"
+ }
+
+ if *bootstrapMode {
+ if len(*argIP) == 0 {
+ argIP = scanLineA("Please enter your IP and port (e.g. 127.0.0.1:30348): ")
+ }
+ } else if *fileReader {
+ *bootstrapMode = true
+ } else {
+ if len(*argEnode) == 0 {
+ argEnode = scanLineA("Please enter the peer's enode: ")
+ }
+ peer := enode.MustParseV4(*argEnode)
+ peers = append(peers, peer)
+ }
+
+ if *mailServerMode {
+ if len(msPassword) == 0 {
+ msPassword, err = console.Stdin.PromptPassword("Please enter the Mail Server password: ")
+ if err != nil {
+ utils.Fatalf("Failed to read Mail Server password: %s", err)
+ }
+ }
+ }
+
+ cfg := &whisper.Config{
+ MaxMessageSize: uint32(*argMaxSize),
+ MinimumAcceptedPOW: *argPoW,
+ }
+
+ shh = whisper.New(cfg)
+
+ if *argPoW != whisper.DefaultMinimumPoW {
+ err := shh.SetMinimumPoW(*argPoW)
+ if err != nil {
+ utils.Fatalf("Failed to set PoW: %s", err)
+ }
+ }
+
+ if uint32(*argMaxSize) != whisper.DefaultMaxMessageSize {
+ err := shh.SetMaxMessageSize(uint32(*argMaxSize))
+ if err != nil {
+ utils.Fatalf("Failed to set max message size: %s", err)
+ }
+ }
+
+ asymKeyID, err = shh.NewKeyPair()
+ if err != nil {
+ utils.Fatalf("Failed to generate a new key pair: %s", err)
+ }
+
+ asymKey, err = shh.GetPrivateKey(asymKeyID)
+ if err != nil {
+ utils.Fatalf("Failed to retrieve a new key pair: %s", err)
+ }
+
+ if nodeid == nil {
+ tmpID, err := shh.NewKeyPair()
+ if err != nil {
+ utils.Fatalf("Failed to generate a new key pair: %s", err)
+ }
+
+ nodeid, err = shh.GetPrivateKey(tmpID)
+ if err != nil {
+ utils.Fatalf("Failed to retrieve a new key pair: %s", err)
+ }
+ }
+
+ maxPeers := 80
+ if *bootstrapMode {
+ maxPeers = 800
+ }
+
+ _, err = crand.Read(entropy[:])
+ if err != nil {
+ utils.Fatalf("crypto/rand failed: %s", err)
+ }
+
+ if *mailServerMode {
+ shh.RegisterServer(&mailServer)
+ if err := mailServer.Init(shh, *argDBPath, msPassword, *argServerPoW); err != nil {
+ utils.Fatalf("Failed to init MailServer: %s", err)
+ }
+ }
+
+ server = &p2p.Server{
+ Config: p2p.Config{
+ PrivateKey: nodeid,
+ MaxPeers: maxPeers,
+ Name: common.MakeName("wnode", "6.0"),
+ Protocols: shh.Protocols(),
+ ListenAddr: *argIP,
+ NAT: nat.Any(),
+ BootstrapNodes: peers,
+ StaticNodes: peers,
+ TrustedNodes: peers,
+ },
+ }
+}
+
+func startServer() error {
+ err := server.Start()
+ if err != nil {
+ fmt.Printf("Failed to start Whisper peer: %s.", err)
+ return err
+ }
+
+ fmt.Printf("my public key: %s \n", common.ToHex(crypto.FromECDSAPub(&asymKey.PublicKey)))
+ fmt.Println(server.NodeInfo().Enode)
+
+ if *bootstrapMode {
+ configureNode()
+ fmt.Println("Bootstrap Whisper node started")
+ } else {
+ fmt.Println("Whisper node started")
+ // first see if we can establish connection, then ask for user input
+ waitForConnection(true)
+ configureNode()
+ }
+
+ if *fileExMode {
+ fmt.Printf("Please type the file name to be send. To quit type: '%s'\n", quitCommand)
+ } else if *fileReader {
+ fmt.Printf("Please type the file name to be decrypted. To quit type: '%s'\n", quitCommand)
+ } else if !*forwarderMode {
+ fmt.Printf("Please type the message. To quit type: '%s'\n", quitCommand)
+ }
+ return nil
+}
+
+func configureNode() {
+ var err error
+ var p2pAccept bool
+
+ if *forwarderMode {
+ return
+ }
+
+ if *asymmetricMode {
+ if len(*argPub) == 0 {
+ s := scanLine("Please enter the peer's public key: ")
+ b := common.FromHex(s)
+ if b == nil {
+ utils.Fatalf("Error: can not convert hexadecimal string")
+ }
+ if pub, err = crypto.UnmarshalPubkey(b); err != nil {
+ utils.Fatalf("Error: invalid peer public key")
+ }
+ }
+ }
+
+ if *requestMail {
+ p2pAccept = true
+ if len(msPassword) == 0 {
+ msPassword, err = console.Stdin.PromptPassword("Please enter the Mail Server password: ")
+ if err != nil {
+ utils.Fatalf("Failed to read Mail Server password: %s", err)
+ }
+ }
+ }
+
+ if !*asymmetricMode && !*forwarderMode {
+ if len(symPass) == 0 {
+ symPass, err = console.Stdin.PromptPassword("Please enter the password for symmetric encryption: ")
+ if err != nil {
+ utils.Fatalf("Failed to read passphrase: %v", err)
+ }
+ }
+
+ symKeyID, err := shh.AddSymKeyFromPassword(symPass)
+ if err != nil {
+ utils.Fatalf("Failed to create symmetric key: %s", err)
+ }
+ symKey, err = shh.GetSymKey(symKeyID)
+ if err != nil {
+ utils.Fatalf("Failed to save symmetric key: %s", err)
+ }
+ if len(*argTopic) == 0 {
+ generateTopic([]byte(symPass))
+ }
+
+ fmt.Printf("Filter is configured for the topic: %x \n", topic)
+ }
+
+ if *mailServerMode {
+ if len(*argDBPath) == 0 {
+ argDBPath = scanLineA("Please enter the path to DB file: ")
+ }
+ }
+
+ symFilter := whisper.Filter{
+ KeySym: symKey,
+ Topics: [][]byte{topic[:]},
+ AllowP2P: p2pAccept,
+ }
+ symFilterID, err = shh.Subscribe(&symFilter)
+ if err != nil {
+ utils.Fatalf("Failed to install filter: %s", err)
+ }
+
+ asymFilter := whisper.Filter{
+ KeyAsym: asymKey,
+ Topics: [][]byte{topic[:]},
+ AllowP2P: p2pAccept,
+ }
+ asymFilterID, err = shh.Subscribe(&asymFilter)
+ if err != nil {
+ utils.Fatalf("Failed to install filter: %s", err)
+ }
+}
+
+func generateTopic(password []byte) {
+ x := pbkdf2.Key(password, password, 4096, 128, sha512.New)
+ for i := 0; i < len(x); i++ {
+ topic[i%whisper.TopicLength] ^= x[i]
+ }
+}
+
+func waitForConnection(timeout bool) {
+ var cnt int
+ var connected bool
+ for !connected {
+ time.Sleep(time.Millisecond * 50)
+ connected = server.PeerCount() > 0
+ if timeout {
+ cnt++
+ if cnt > 1000 {
+ utils.Fatalf("Timeout expired, failed to connect")
+ }
+ }
+ }
+
+ fmt.Println("Connected to peer.")
+}
+
+func run() {
+ err := startServer()
+ if err != nil {
+ return
+ }
+ defer server.Stop()
+ shh.Start(nil)
+ defer shh.Stop()
+
+ if !*forwarderMode {
+ go messageLoop()
+ }
+
+ if *requestMail {
+ requestExpiredMessagesLoop()
+ } else if *fileExMode {
+ sendFilesLoop()
+ } else if *fileReader {
+ fileReaderLoop()
+ } else {
+ sendLoop()
+ }
+}
+
+func shutdown() {
+ close(done)
+ mailServer.Close()
+}
+
+func sendLoop() {
+ for {
+ s := scanLine("")
+ if s == quitCommand {
+ fmt.Println("Quit command received")
+ return
+ }
+ sendMsg([]byte(s))
+ if *asymmetricMode {
+ // print your own message for convenience,
+ // because in asymmetric mode it is impossible to decrypt it
+ timestamp := time.Now().Unix()
+ from := crypto.PubkeyToAddress(asymKey.PublicKey)
+ fmt.Printf("\n%d <%x>: %s\n", timestamp, from, s)
+ }
+ }
+}
+
+func sendFilesLoop() {
+ for {
+ s := scanLine("")
+ if s == quitCommand {
+ fmt.Println("Quit command received")
+ return
+ }
+ b, err := ioutil.ReadFile(s)
+ if err != nil {
+ fmt.Printf(">>> Error: %s \n", err)
+ } else {
+ h := sendMsg(b)
+ if (h == common.Hash{}) {
+ fmt.Printf(">>> Error: message was not sent \n")
+ } else {
+ timestamp := time.Now().Unix()
+ from := crypto.PubkeyToAddress(asymKey.PublicKey)
+ fmt.Printf("\n%d <%x>: sent message with hash %x\n", timestamp, from, h)
+ }
+ }
+ }
+}
+
+func fileReaderLoop() {
+ watcher1 := shh.GetFilter(symFilterID)
+ watcher2 := shh.GetFilter(asymFilterID)
+ if watcher1 == nil && watcher2 == nil {
+ fmt.Println("Error: neither symmetric nor asymmetric filter is installed")
+ return
+ }
+
+ for {
+ s := scanLine("")
+ if s == quitCommand {
+ fmt.Println("Quit command received")
+ return
+ }
+ raw, err := ioutil.ReadFile(s)
+ if err != nil {
+ fmt.Printf(">>> Error: %s \n", err)
+ } else {
+ env := whisper.Envelope{Data: raw} // the topic is zero
+ msg := env.Open(watcher1) // force-open envelope regardless of the topic
+ if msg == nil {
+ msg = env.Open(watcher2)
+ }
+ if msg == nil {
+ fmt.Printf(">>> Error: failed to decrypt the message \n")
+ } else {
+ printMessageInfo(msg)
+ }
+ }
+ }
+}
+
+func scanLine(prompt string) string {
+ if len(prompt) > 0 {
+ fmt.Print(prompt)
+ }
+ txt, err := input.ReadString('\n')
+ if err != nil {
+ utils.Fatalf("input error: %s", err)
+ }
+ txt = strings.TrimRight(txt, "\n\r")
+ return txt
+}
+
+func scanLineA(prompt string) *string {
+ s := scanLine(prompt)
+ return &s
+}
+
+func scanUint(prompt string) uint32 {
+ s := scanLine(prompt)
+ i, err := strconv.Atoi(s)
+ if err != nil {
+ utils.Fatalf("Fail to parse the lower time limit: %s", err)
+ }
+ return uint32(i)
+}
+
+func sendMsg(payload []byte) common.Hash {
+ params := whisper.MessageParams{
+ Src: asymKey,
+ Dst: pub,
+ KeySym: symKey,
+ Payload: payload,
+ Topic: topic,
+ TTL: uint32(*argTTL),
+ PoW: *argPoW,
+ WorkTime: uint32(*argWorkTime),
+ }
+
+ msg, err := whisper.NewSentMessage(¶ms)
+ if err != nil {
+ utils.Fatalf("failed to create new message: %s", err)
+ }
+
+ envelope, err := msg.Wrap(¶ms)
+ if err != nil {
+ fmt.Printf("failed to seal message: %v \n", err)
+ return common.Hash{}
+ }
+
+ err = shh.Send(envelope)
+ if err != nil {
+ fmt.Printf("failed to send message: %v \n", err)
+ return common.Hash{}
+ }
+
+ return envelope.Hash()
+}
+
+func messageLoop() {
+ sf := shh.GetFilter(symFilterID)
+ if sf == nil {
+ utils.Fatalf("symmetric filter is not installed")
+ }
+
+ af := shh.GetFilter(asymFilterID)
+ if af == nil {
+ utils.Fatalf("asymmetric filter is not installed")
+ }
+
+ ticker := time.NewTicker(time.Millisecond * 50)
+
+ for {
+ select {
+ case <-ticker.C:
+ m1 := sf.Retrieve()
+ m2 := af.Retrieve()
+ messages := append(m1, m2...)
+ for _, msg := range messages {
+ reportedOnce := false
+ if !*fileExMode && len(msg.Payload) <= 2048 {
+ printMessageInfo(msg)
+ reportedOnce = true
+ }
+
+ // All messages are saved upon specifying argSaveDir.
+ // fileExMode only specifies how messages are displayed on the console after they are saved.
+ // if fileExMode == true, only the hashes are displayed, since messages might be too big.
+ if len(*argSaveDir) > 0 {
+ writeMessageToFile(*argSaveDir, msg, !reportedOnce)
+ }
+ }
+ case <-done:
+ return
+ }
+ }
+}
+
+func printMessageInfo(msg *whisper.ReceivedMessage) {
+ timestamp := fmt.Sprintf("%d", msg.Sent) // unix timestamp for diagnostics
+ text := string(msg.Payload)
+
+ var address common.Address
+ if msg.Src != nil {
+ address = crypto.PubkeyToAddress(*msg.Src)
+ }
+
+ if whisper.IsPubKeyEqual(msg.Src, &asymKey.PublicKey) {
+ fmt.Printf("\n%s <%x>: %s\n", timestamp, address, text) // message from myself
+ } else {
+ fmt.Printf("\n%s [%x]: %s\n", timestamp, address, text) // message from a peer
+ }
+}
+
+func writeMessageToFile(dir string, msg *whisper.ReceivedMessage, show bool) {
+ if len(dir) == 0 {
+ return
+ }
+
+ timestamp := fmt.Sprintf("%d", msg.Sent)
+ name := fmt.Sprintf("%x", msg.EnvelopeHash)
+
+ var address common.Address
+ if msg.Src != nil {
+ address = crypto.PubkeyToAddress(*msg.Src)
+ }
+
+ env := shh.GetEnvelope(msg.EnvelopeHash)
+ if env == nil {
+ fmt.Printf("\nUnexpected error: envelope not found: %x\n", msg.EnvelopeHash)
+ return
+ }
+
+ // this is a sample code; uncomment if you don't want to save your own messages.
+ //if whisper.IsPubKeyEqual(msg.Src, &asymKey.PublicKey) {
+ // fmt.Printf("\n%s <%x>: message from myself received, not saved: '%s'\n", timestamp, address, name)
+ // return
+ //}
+
+ fullpath := filepath.Join(dir, name)
+ err := ioutil.WriteFile(fullpath, env.Data, 0644)
+ if err != nil {
+ fmt.Printf("\n%s {%x}: message received but not saved: %s\n", timestamp, address, err)
+ } else if show {
+ fmt.Printf("\n%s {%x}: message received and saved as '%s' (%d bytes)\n", timestamp, address, name, len(env.Data))
+ }
+}
+
+func requestExpiredMessagesLoop() {
+ var key, peerID, bloom []byte
+ var timeLow, timeUpp uint32
+ var t string
+ var xt whisper.TopicType
+
+ keyID, err := shh.AddSymKeyFromPassword(msPassword)
+ if err != nil {
+ utils.Fatalf("Failed to create symmetric key for mail request: %s", err)
+ }
+ key, err = shh.GetSymKey(keyID)
+ if err != nil {
+ utils.Fatalf("Failed to save symmetric key for mail request: %s", err)
+ }
+ peerID = extractIDFromEnode(*argEnode)
+ shh.AllowP2PMessagesFromPeer(peerID)
+
+ for {
+ timeLow = scanUint("Please enter the lower limit of the time range (unix timestamp): ")
+ timeUpp = scanUint("Please enter the upper limit of the time range (unix timestamp): ")
+ t = scanLine("Enter the topic (hex). Press enter to request all messages, regardless of the topic: ")
+ if len(t) == whisper.TopicLength*2 {
+ x, err := hex.DecodeString(t)
+ if err != nil {
+ fmt.Printf("Failed to parse the topic: %s \n", err)
+ continue
+ }
+ xt = whisper.BytesToTopic(x)
+ bloom = whisper.TopicToBloom(xt)
+ obfuscateBloom(bloom)
+ } else if len(t) == 0 {
+ bloom = whisper.MakeFullNodeBloom()
+ } else {
+ fmt.Println("Error: topic is invalid, request aborted")
+ continue
+ }
+
+ if timeUpp == 0 {
+ timeUpp = 0xFFFFFFFF
+ }
+
+ data := make([]byte, 8, 8+whisper.BloomFilterSize)
+ binary.BigEndian.PutUint32(data, timeLow)
+ binary.BigEndian.PutUint32(data[4:], timeUpp)
+ data = append(data, bloom...)
+
+ var params whisper.MessageParams
+ params.PoW = *argServerPoW
+ params.Payload = data
+ params.KeySym = key
+ params.Src = asymKey
+ params.WorkTime = 5
+
+ msg, err := whisper.NewSentMessage(¶ms)
+ if err != nil {
+ utils.Fatalf("failed to create new message: %s", err)
+ }
+ env, err := msg.Wrap(¶ms)
+ if err != nil {
+ utils.Fatalf("Wrap failed: %s", err)
+ }
+
+ err = shh.RequestHistoricMessages(peerID, env)
+ if err != nil {
+ utils.Fatalf("Failed to send P2P message: %s", err)
+ }
+
+ time.Sleep(time.Second * 5)
+ }
+}
+
+func extractIDFromEnode(s string) []byte {
+ n, err := enode.ParseV4(s)
+ if err != nil {
+ utils.Fatalf("Failed to parse enode: %s", err)
+ }
+ return n.ID().Bytes()
+}
+
+// obfuscateBloom adds 16 random bits to the bloom
+// filter, in order to obfuscate the containing topics.
+// it does so deterministically within every session.
+// despite additional bits, it will match on average
+// 32000 times less messages than full node's bloom filter.
+func obfuscateBloom(bloom []byte) {
+ const half = entropySize / 2
+ for i := 0; i < half; i++ {
+ x := int(entropy[i])
+ if entropy[half+i] < 128 {
+ x += 256
+ }
+
+ bloom[x/8] = 1 << uint(x%8) // set the bit number X
+ }
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/common/compiler/helpers.go b/vendor/github.com/ethereum/go-ethereum/common/compiler/helpers.go
new file mode 100644
index 00000000..4de706f6
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/common/compiler/helpers.go
@@ -0,0 +1,64 @@
+// Copyright 2019 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+// Package compiler wraps the Solidity and Vyper compiler executables (solc; vyper).
+package compiler
+
+import (
+ "bytes"
+ "io/ioutil"
+ "regexp"
+)
+
+var versionRegexp = regexp.MustCompile(`([0-9]+)\.([0-9]+)\.([0-9]+)`)
+
+// Contract contains information about a compiled contract, alongside its code and runtime code.
+type Contract struct {
+ Code string `json:"code"`
+ RuntimeCode string `json:"runtime-code"`
+ Info ContractInfo `json:"info"`
+}
+
+// ContractInfo contains information about a compiled contract, including access
+// to the ABI definition, source mapping, user and developer docs, and metadata.
+//
+// Depending on the source, language version, compiler version, and compiler
+// options will provide information about how the contract was compiled.
+type ContractInfo struct {
+ Source string `json:"source"`
+ Language string `json:"language"`
+ LanguageVersion string `json:"languageVersion"`
+ CompilerVersion string `json:"compilerVersion"`
+ CompilerOptions string `json:"compilerOptions"`
+ SrcMap interface{} `json:"srcMap"`
+ SrcMapRuntime string `json:"srcMapRuntime"`
+ AbiDefinition interface{} `json:"abiDefinition"`
+ UserDoc interface{} `json:"userDoc"`
+ DeveloperDoc interface{} `json:"developerDoc"`
+ Metadata string `json:"metadata"`
+}
+
+func slurpFiles(files []string) (string, error) {
+ var concat bytes.Buffer
+ for _, file := range files {
+ content, err := ioutil.ReadFile(file)
+ if err != nil {
+ return "", err
+ }
+ concat.Write(content)
+ }
+ return concat.String(), nil
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/common/compiler/solidity.go b/vendor/github.com/ethereum/go-ethereum/common/compiler/solidity.go
new file mode 100644
index 00000000..7ed9c263
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/common/compiler/solidity.go
@@ -0,0 +1,180 @@
+// Copyright 2019 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+// Package compiler wraps the Solidity and Vyper compiler executables (solc; vyper).
+package compiler
+
+import (
+ "bytes"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "os/exec"
+ "strconv"
+ "strings"
+)
+
+// Solidity contains information about the solidity compiler.
+type Solidity struct {
+ Path, Version, FullVersion string
+ Major, Minor, Patch int
+}
+
+// --combined-output format
+type solcOutput struct {
+ Contracts map[string]struct {
+ BinRuntime string `json:"bin-runtime"`
+ SrcMapRuntime string `json:"srcmap-runtime"`
+ Bin, SrcMap, Abi, Devdoc, Userdoc, Metadata string
+ }
+ Version string
+}
+
+func (s *Solidity) makeArgs() []string {
+ p := []string{
+ "--combined-json", "bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc",
+ "--optimize", // code optimizer switched on
+ }
+ if s.Major > 0 || s.Minor > 4 || s.Patch > 6 {
+ p[1] += ",metadata"
+ }
+ return p
+}
+
+// SolidityVersion runs solc and parses its version output.
+func SolidityVersion(solc string) (*Solidity, error) {
+ if solc == "" {
+ solc = "solc"
+ }
+ var out bytes.Buffer
+ cmd := exec.Command(solc, "--version")
+ cmd.Stdout = &out
+ err := cmd.Run()
+ if err != nil {
+ return nil, err
+ }
+ matches := versionRegexp.FindStringSubmatch(out.String())
+ if len(matches) != 4 {
+ return nil, fmt.Errorf("can't parse solc version %q", out.String())
+ }
+ s := &Solidity{Path: cmd.Path, FullVersion: out.String(), Version: matches[0]}
+ if s.Major, err = strconv.Atoi(matches[1]); err != nil {
+ return nil, err
+ }
+ if s.Minor, err = strconv.Atoi(matches[2]); err != nil {
+ return nil, err
+ }
+ if s.Patch, err = strconv.Atoi(matches[3]); err != nil {
+ return nil, err
+ }
+ return s, nil
+}
+
+// CompileSolidityString builds and returns all the contracts contained within a source string.
+func CompileSolidityString(solc, source string) (map[string]*Contract, error) {
+ if len(source) == 0 {
+ return nil, errors.New("solc: empty source string")
+ }
+ s, err := SolidityVersion(solc)
+ if err != nil {
+ return nil, err
+ }
+ args := append(s.makeArgs(), "--")
+ cmd := exec.Command(s.Path, append(args, "-")...)
+ cmd.Stdin = strings.NewReader(source)
+ return s.run(cmd, source)
+}
+
+// CompileSolidity compiles all given Solidity source files.
+func CompileSolidity(solc string, sourcefiles ...string) (map[string]*Contract, error) {
+ if len(sourcefiles) == 0 {
+ return nil, errors.New("solc: no source files")
+ }
+ source, err := slurpFiles(sourcefiles)
+ if err != nil {
+ return nil, err
+ }
+ s, err := SolidityVersion(solc)
+ if err != nil {
+ return nil, err
+ }
+ args := append(s.makeArgs(), "--")
+ cmd := exec.Command(s.Path, append(args, sourcefiles...)...)
+ return s.run(cmd, source)
+}
+
+func (s *Solidity) run(cmd *exec.Cmd, source string) (map[string]*Contract, error) {
+ var stderr, stdout bytes.Buffer
+ cmd.Stderr = &stderr
+ cmd.Stdout = &stdout
+ if err := cmd.Run(); err != nil {
+ return nil, fmt.Errorf("solc: %v\n%s", err, stderr.Bytes())
+ }
+
+ return ParseCombinedJSON(stdout.Bytes(), source, s.Version, s.Version, strings.Join(s.makeArgs(), " "))
+}
+
+// ParseCombinedJSON takes the direct output of a solc --combined-output run and
+// parses it into a map of string contract name to Contract structs. The
+// provided source, language and compiler version, and compiler options are all
+// passed through into the Contract structs.
+//
+// The solc output is expected to contain ABI, source mapping, user docs, and dev docs.
+//
+// Returns an error if the JSON is malformed or missing data, or if the JSON
+// embedded within the JSON is malformed.
+func ParseCombinedJSON(combinedJSON []byte, source string, languageVersion string, compilerVersion string, compilerOptions string) (map[string]*Contract, error) {
+ var output solcOutput
+ if err := json.Unmarshal(combinedJSON, &output); err != nil {
+ return nil, err
+ }
+
+ // Compilation succeeded, assemble and return the contracts.
+ contracts := make(map[string]*Contract)
+ for name, info := range output.Contracts {
+ // Parse the individual compilation results.
+ var abi interface{}
+ if err := json.Unmarshal([]byte(info.Abi), &abi); err != nil {
+ return nil, fmt.Errorf("solc: error reading abi definition (%v)", err)
+ }
+ var userdoc interface{}
+ if err := json.Unmarshal([]byte(info.Userdoc), &userdoc); err != nil {
+ return nil, fmt.Errorf("solc: error reading user doc: %v", err)
+ }
+ var devdoc interface{}
+ if err := json.Unmarshal([]byte(info.Devdoc), &devdoc); err != nil {
+ return nil, fmt.Errorf("solc: error reading dev doc: %v", err)
+ }
+ contracts[name] = &Contract{
+ Code: "0x" + info.Bin,
+ RuntimeCode: "0x" + info.BinRuntime,
+ Info: ContractInfo{
+ Source: source,
+ Language: "Solidity",
+ LanguageVersion: languageVersion,
+ CompilerVersion: compilerVersion,
+ CompilerOptions: compilerOptions,
+ SrcMap: info.SrcMap,
+ SrcMapRuntime: info.SrcMapRuntime,
+ AbiDefinition: abi,
+ UserDoc: userdoc,
+ DeveloperDoc: devdoc,
+ Metadata: info.Metadata,
+ },
+ }
+ }
+ return contracts, nil
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/common/compiler/test.v.py b/vendor/github.com/ethereum/go-ethereum/common/compiler/test.v.py
new file mode 100644
index 00000000..35af56c8
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/common/compiler/test.v.py
@@ -0,0 +1,3 @@
+@public
+def test():
+ hello: int128
diff --git a/vendor/github.com/ethereum/go-ethereum/common/compiler/test_bad.v.py b/vendor/github.com/ethereum/go-ethereum/common/compiler/test_bad.v.py
new file mode 100644
index 00000000..443ef782
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/common/compiler/test_bad.v.py
@@ -0,0 +1,3 @@
+lic
+def test():
+ hello: int128
diff --git a/vendor/github.com/ethereum/go-ethereum/common/compiler/vyper.go b/vendor/github.com/ethereum/go-ethereum/common/compiler/vyper.go
new file mode 100644
index 00000000..a9bca95e
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/common/compiler/vyper.go
@@ -0,0 +1,144 @@
+// Copyright 2019 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+// Package compiler wraps the Solidity and Vyper compiler executables (solc; vyper).
+package compiler
+
+import (
+ "bytes"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "os/exec"
+ "strconv"
+ "strings"
+)
+
+// Vyper contains information about the vyper compiler.
+type Vyper struct {
+ Path, Version, FullVersion string
+ Major, Minor, Patch int
+}
+
+func (s *Vyper) makeArgs() []string {
+ p := []string{
+ "-f", "combined_json",
+ }
+ return p
+}
+
+// VyperVersion runs vyper and parses its version output.
+func VyperVersion(vyper string) (*Vyper, error) {
+ if vyper == "" {
+ vyper = "vyper"
+ }
+ var out bytes.Buffer
+ cmd := exec.Command(vyper, "--version")
+ cmd.Stdout = &out
+ err := cmd.Run()
+ if err != nil {
+ return nil, err
+ }
+ matches := versionRegexp.FindStringSubmatch(out.String())
+ if len(matches) != 4 {
+ return nil, fmt.Errorf("can't parse vyper version %q", out.String())
+ }
+ s := &Vyper{Path: cmd.Path, FullVersion: out.String(), Version: matches[0]}
+ if s.Major, err = strconv.Atoi(matches[1]); err != nil {
+ return nil, err
+ }
+ if s.Minor, err = strconv.Atoi(matches[2]); err != nil {
+ return nil, err
+ }
+ if s.Patch, err = strconv.Atoi(matches[3]); err != nil {
+ return nil, err
+ }
+ return s, nil
+}
+
+// CompileVyper compiles all given Vyper source files.
+func CompileVyper(vyper string, sourcefiles ...string) (map[string]*Contract, error) {
+ if len(sourcefiles) == 0 {
+ return nil, errors.New("vyper: no source files")
+ }
+ source, err := slurpFiles(sourcefiles)
+ if err != nil {
+ return nil, err
+ }
+ s, err := VyperVersion(vyper)
+ if err != nil {
+ return nil, err
+ }
+ args := s.makeArgs()
+ cmd := exec.Command(s.Path, append(args, sourcefiles...)...)
+ return s.run(cmd, source)
+}
+
+func (s *Vyper) run(cmd *exec.Cmd, source string) (map[string]*Contract, error) {
+ var stderr, stdout bytes.Buffer
+ cmd.Stderr = &stderr
+ cmd.Stdout = &stdout
+ if err := cmd.Run(); err != nil {
+ return nil, fmt.Errorf("vyper: %v\n%s", err, stderr.Bytes())
+ }
+
+ return ParseVyperJSON(stdout.Bytes(), source, s.Version, s.Version, strings.Join(s.makeArgs(), " "))
+}
+
+// ParseVyperJSON takes the direct output of a vyper --f combined_json run and
+// parses it into a map of string contract name to Contract structs. The
+// provided source, language and compiler version, and compiler options are all
+// passed through into the Contract structs.
+//
+// The vyper output is expected to contain ABI and source mapping.
+//
+// Returns an error if the JSON is malformed or missing data, or if the JSON
+// embedded within the JSON is malformed.
+func ParseVyperJSON(combinedJSON []byte, source string, languageVersion string, compilerVersion string, compilerOptions string) (map[string]*Contract, error) {
+ var output map[string]interface{}
+ if err := json.Unmarshal(combinedJSON, &output); err != nil {
+ return nil, err
+ }
+
+ // Compilation succeeded, assemble and return the contracts.
+ contracts := make(map[string]*Contract)
+ for name, info := range output {
+ // Parse the individual compilation results.
+ if name == "version" {
+ continue
+ }
+ c := info.(map[string]interface{})
+
+ contracts[name] = &Contract{
+ Code: c["bytecode"].(string),
+ RuntimeCode: c["bytecode_runtime"].(string),
+ Info: ContractInfo{
+ Source: source,
+ Language: "Vyper",
+ LanguageVersion: languageVersion,
+ CompilerVersion: compilerVersion,
+ CompilerOptions: compilerOptions,
+ SrcMap: c["source_map"],
+ SrcMapRuntime: "",
+ AbiDefinition: c["abi"],
+ UserDoc: "",
+ DeveloperDoc: "",
+ Metadata: "",
+ },
+ }
+ }
+ return contracts, nil
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/common/fdlimit/fdlimit_darwin.go b/vendor/github.com/ethereum/go-ethereum/common/fdlimit/fdlimit_darwin.go
new file mode 100644
index 00000000..88dd0f56
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/common/fdlimit/fdlimit_darwin.go
@@ -0,0 +1,71 @@
+// Copyright 2019 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+package fdlimit
+
+import "syscall"
+
+// hardlimit is the number of file descriptors allowed at max by the kernel.
+const hardlimit = 10240
+
+// Raise tries to maximize the file descriptor allowance of this process
+// to the maximum hard-limit allowed by the OS.
+// Returns the size it was set to (may differ from the desired 'max')
+func Raise(max uint64) (uint64, error) {
+ // Get the current limit
+ var limit syscall.Rlimit
+ if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &limit); err != nil {
+ return 0, err
+ }
+ // Try to update the limit to the max allowance
+ limit.Cur = limit.Max
+ if limit.Cur > max {
+ limit.Cur = max
+ }
+ if err := syscall.Setrlimit(syscall.RLIMIT_NOFILE, &limit); err != nil {
+ return 0, err
+ }
+ // MacOS can silently apply further caps, so retrieve the actually set limit
+ if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &limit); err != nil {
+ return 0, err
+ }
+ return limit.Cur, nil
+}
+
+// Current retrieves the number of file descriptors allowed to be opened by this
+// process.
+func Current() (int, error) {
+ var limit syscall.Rlimit
+ if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &limit); err != nil {
+ return 0, err
+ }
+ return int(limit.Cur), nil
+}
+
+// Maximum retrieves the maximum number of file descriptors this process is
+// allowed to request for itself.
+func Maximum() (int, error) {
+ // Retrieve the maximum allowed by dynamic OS limits
+ var limit syscall.Rlimit
+ if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &limit); err != nil {
+ return 0, err
+ }
+ // Cap it to OPEN_MAX (10240) because macos is a special snowflake
+ if limit.Max > hardlimit {
+ limit.Max = hardlimit
+ }
+ return int(limit.Max), nil
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/common/fdlimit/fdlimit_freebsd.go b/vendor/github.com/ethereum/go-ethereum/common/fdlimit/fdlimit_freebsd.go
new file mode 100644
index 00000000..0d872713
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/common/fdlimit/fdlimit_freebsd.go
@@ -0,0 +1,67 @@
+// Copyright 2016 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+// +build freebsd
+
+package fdlimit
+
+import "syscall"
+
+// This file is largely identical to fdlimit_unix.go,
+// but Rlimit fields have type int64 on FreeBSD so it needs
+// an extra conversion.
+
+// Raise tries to maximize the file descriptor allowance of this process
+// to the maximum hard-limit allowed by the OS.
+func Raise(max uint64) (uint64, error) {
+ // Get the current limit
+ var limit syscall.Rlimit
+ if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &limit); err != nil {
+ return 0, err
+ }
+ // Try to update the limit to the max allowance
+ limit.Cur = limit.Max
+ if limit.Cur > int64(max) {
+ limit.Cur = int64(max)
+ }
+ if err := syscall.Setrlimit(syscall.RLIMIT_NOFILE, &limit); err != nil {
+ return 0, err
+ }
+ if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &limit); err != nil {
+ return 0, err
+ }
+ return uint64(limit.Cur), nil
+}
+
+// Current retrieves the number of file descriptors allowed to be opened by this
+// process.
+func Current() (int, error) {
+ var limit syscall.Rlimit
+ if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &limit); err != nil {
+ return 0, err
+ }
+ return int(limit.Cur), nil
+}
+
+// Maximum retrieves the maximum number of file descriptors this process is
+// allowed to request for itself.
+func Maximum() (int, error) {
+ var limit syscall.Rlimit
+ if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &limit); err != nil {
+ return 0, err
+ }
+ return int(limit.Max), nil
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/common/fdlimit/fdlimit_unix.go b/vendor/github.com/ethereum/go-ethereum/common/fdlimit/fdlimit_unix.go
new file mode 100644
index 00000000..e5a575f7
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/common/fdlimit/fdlimit_unix.go
@@ -0,0 +1,65 @@
+// Copyright 2016 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+// +build linux netbsd openbsd solaris
+
+package fdlimit
+
+import "syscall"
+
+// Raise tries to maximize the file descriptor allowance of this process
+// to the maximum hard-limit allowed by the OS.
+// Returns the size it was set to (may differ from the desired 'max')
+func Raise(max uint64) (uint64, error) {
+ // Get the current limit
+ var limit syscall.Rlimit
+ if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &limit); err != nil {
+ return 0, err
+ }
+ // Try to update the limit to the max allowance
+ limit.Cur = limit.Max
+ if limit.Cur > max {
+ limit.Cur = max
+ }
+ if err := syscall.Setrlimit(syscall.RLIMIT_NOFILE, &limit); err != nil {
+ return 0, err
+ }
+ // MacOS can silently apply further caps, so retrieve the actually set limit
+ if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &limit); err != nil {
+ return 0, err
+ }
+ return limit.Cur, nil
+}
+
+// Current retrieves the number of file descriptors allowed to be opened by this
+// process.
+func Current() (int, error) {
+ var limit syscall.Rlimit
+ if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &limit); err != nil {
+ return 0, err
+ }
+ return int(limit.Cur), nil
+}
+
+// Maximum retrieves the maximum number of file descriptors this process is
+// allowed to request for itself.
+func Maximum() (int, error) {
+ var limit syscall.Rlimit
+ if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &limit); err != nil {
+ return 0, err
+ }
+ return int(limit.Max), nil
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/common/fdlimit/fdlimit_windows.go b/vendor/github.com/ethereum/go-ethereum/common/fdlimit/fdlimit_windows.go
new file mode 100644
index 00000000..f4721536
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/common/fdlimit/fdlimit_windows.go
@@ -0,0 +1,50 @@
+// Copyright 2018 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+package fdlimit
+
+import "fmt"
+
+// hardlimit is the number of file descriptors allowed at max by the kernel.
+const hardlimit = 16384
+
+// Raise tries to maximize the file descriptor allowance of this process
+// to the maximum hard-limit allowed by the OS.
+func Raise(max uint64) (uint64, error) {
+ // This method is NOP by design:
+ // * Linux/Darwin counterparts need to manually increase per process limits
+ // * On Windows Go uses the CreateFile API, which is limited to 16K files, non
+ // changeable from within a running process
+ // This way we can always "request" raising the limits, which will either have
+ // or not have effect based on the platform we're running on.
+ if max > hardlimit {
+ return hardlimit, fmt.Errorf("file descriptor limit (%d) reached", hardlimit)
+ }
+ return max, nil
+}
+
+// Current retrieves the number of file descriptors allowed to be opened by this
+// process.
+func Current() (int, error) {
+ // Please see Raise for the reason why we use hard coded 16K as the limit
+ return hardlimit, nil
+}
+
+// Maximum retrieves the maximum number of file descriptors this process is
+// allowed to request for itself.
+func Maximum() (int, error) {
+ return Current()
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/console/bridge.go b/vendor/github.com/ethereum/go-ethereum/console/bridge.go
new file mode 100644
index 00000000..bb14abca
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/console/bridge.go
@@ -0,0 +1,438 @@
+// Copyright 2016 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+package console
+
+import (
+ "encoding/json"
+ "fmt"
+ "io"
+ "strings"
+ "time"
+
+ "github.com/ethereum/go-ethereum/accounts/scwallet"
+ "github.com/ethereum/go-ethereum/accounts/usbwallet"
+ "github.com/ethereum/go-ethereum/log"
+ "github.com/ethereum/go-ethereum/rpc"
+ "github.com/robertkrimen/otto"
+)
+
+// bridge is a collection of JavaScript utility methods to bride the .js runtime
+// environment and the Go RPC connection backing the remote method calls.
+type bridge struct {
+ client *rpc.Client // RPC client to execute Ethereum requests through
+ prompter UserPrompter // Input prompter to allow interactive user feedback
+ printer io.Writer // Output writer to serialize any display strings to
+}
+
+// newBridge creates a new JavaScript wrapper around an RPC client.
+func newBridge(client *rpc.Client, prompter UserPrompter, printer io.Writer) *bridge {
+ return &bridge{
+ client: client,
+ prompter: prompter,
+ printer: printer,
+ }
+}
+
+// NewAccount is a wrapper around the personal.newAccount RPC method that uses a
+// non-echoing password prompt to acquire the passphrase and executes the original
+// RPC method (saved in jeth.newAccount) with it to actually execute the RPC call.
+func (b *bridge) NewAccount(call otto.FunctionCall) (response otto.Value) {
+ var (
+ password string
+ confirm string
+ err error
+ )
+ switch {
+ // No password was specified, prompt the user for it
+ case len(call.ArgumentList) == 0:
+ if password, err = b.prompter.PromptPassword("Passphrase: "); err != nil {
+ throwJSException(err.Error())
+ }
+ if confirm, err = b.prompter.PromptPassword("Repeat passphrase: "); err != nil {
+ throwJSException(err.Error())
+ }
+ if password != confirm {
+ throwJSException("passphrases don't match!")
+ }
+
+ // A single string password was specified, use that
+ case len(call.ArgumentList) == 1 && call.Argument(0).IsString():
+ password, _ = call.Argument(0).ToString()
+
+ // Otherwise fail with some error
+ default:
+ throwJSException("expected 0 or 1 string argument")
+ }
+ // Password acquired, execute the call and return
+ ret, err := call.Otto.Call("jeth.newAccount", nil, password)
+ if err != nil {
+ throwJSException(err.Error())
+ }
+ return ret
+}
+
+// OpenWallet is a wrapper around personal.openWallet which can interpret and
+// react to certain error messages, such as the Trezor PIN matrix request.
+func (b *bridge) OpenWallet(call otto.FunctionCall) (response otto.Value) {
+ // Make sure we have a wallet specified to open
+ if !call.Argument(0).IsString() {
+ throwJSException("first argument must be the wallet URL to open")
+ }
+ wallet := call.Argument(0)
+
+ var passwd otto.Value
+ if call.Argument(1).IsUndefined() || call.Argument(1).IsNull() {
+ passwd, _ = otto.ToValue("")
+ } else {
+ passwd = call.Argument(1)
+ }
+ // Open the wallet and return if successful in itself
+ val, err := call.Otto.Call("jeth.openWallet", nil, wallet, passwd)
+ if err == nil {
+ return val
+ }
+
+ // Wallet open failed, report error unless it's a PIN or PUK entry
+ switch {
+ case strings.HasSuffix(err.Error(), usbwallet.ErrTrezorPINNeeded.Error()):
+ val, err = b.readPinAndReopenWallet(call)
+ if err == nil {
+ return val
+ }
+ val, err = b.readPassphraseAndReopenWallet(call)
+ if err != nil {
+ throwJSException(err.Error())
+ }
+
+ case strings.HasSuffix(err.Error(), scwallet.ErrPairingPasswordNeeded.Error()):
+ // PUK input requested, fetch from the user and call open again
+ if input, err := b.prompter.PromptPassword("Please enter the pairing password: "); err != nil {
+ throwJSException(err.Error())
+ } else {
+ passwd, _ = otto.ToValue(input)
+ }
+ if val, err = call.Otto.Call("jeth.openWallet", nil, wallet, passwd); err != nil {
+ if !strings.HasSuffix(err.Error(), scwallet.ErrPINNeeded.Error()) {
+ throwJSException(err.Error())
+ } else {
+ // PIN input requested, fetch from the user and call open again
+ if input, err := b.prompter.PromptPassword("Please enter current PIN: "); err != nil {
+ throwJSException(err.Error())
+ } else {
+ passwd, _ = otto.ToValue(input)
+ }
+ if val, err = call.Otto.Call("jeth.openWallet", nil, wallet, passwd); err != nil {
+ throwJSException(err.Error())
+ }
+ }
+ }
+
+ case strings.HasSuffix(err.Error(), scwallet.ErrPINUnblockNeeded.Error()):
+ // PIN unblock requested, fetch PUK and new PIN from the user
+ var pukpin string
+ if input, err := b.prompter.PromptPassword("Please enter current PUK: "); err != nil {
+ throwJSException(err.Error())
+ } else {
+ pukpin = input
+ }
+ if input, err := b.prompter.PromptPassword("Please enter new PIN: "); err != nil {
+ throwJSException(err.Error())
+ } else {
+ pukpin += input
+ }
+ passwd, _ = otto.ToValue(pukpin)
+ if val, err = call.Otto.Call("jeth.openWallet", nil, wallet, passwd); err != nil {
+ throwJSException(err.Error())
+ }
+
+ case strings.HasSuffix(err.Error(), scwallet.ErrPINNeeded.Error()):
+ // PIN input requested, fetch from the user and call open again
+ if input, err := b.prompter.PromptPassword("Please enter current PIN: "); err != nil {
+ throwJSException(err.Error())
+ } else {
+ passwd, _ = otto.ToValue(input)
+ }
+ if val, err = call.Otto.Call("jeth.openWallet", nil, wallet, passwd); err != nil {
+ throwJSException(err.Error())
+ }
+
+ default:
+ // Unknown error occurred, drop to the user
+ throwJSException(err.Error())
+ }
+ return val
+}
+
+func (b *bridge) readPassphraseAndReopenWallet(call otto.FunctionCall) (otto.Value, error) {
+ var passwd otto.Value
+ wallet := call.Argument(0)
+ if input, err := b.prompter.PromptPassword("Please enter your passphrase: "); err != nil {
+ throwJSException(err.Error())
+ } else {
+ passwd, _ = otto.ToValue(input)
+ }
+ return call.Otto.Call("jeth.openWallet", nil, wallet, passwd)
+}
+
+func (b *bridge) readPinAndReopenWallet(call otto.FunctionCall) (otto.Value, error) {
+ var passwd otto.Value
+ wallet := call.Argument(0)
+ // Trezor PIN matrix input requested, display the matrix to the user and fetch the data
+ fmt.Fprintf(b.printer, "Look at the device for number positions\n\n")
+ fmt.Fprintf(b.printer, "7 | 8 | 9\n")
+ fmt.Fprintf(b.printer, "--+---+--\n")
+ fmt.Fprintf(b.printer, "4 | 5 | 6\n")
+ fmt.Fprintf(b.printer, "--+---+--\n")
+ fmt.Fprintf(b.printer, "1 | 2 | 3\n\n")
+
+ if input, err := b.prompter.PromptPassword("Please enter current PIN: "); err != nil {
+ throwJSException(err.Error())
+ } else {
+ passwd, _ = otto.ToValue(input)
+ }
+ return call.Otto.Call("jeth.openWallet", nil, wallet, passwd)
+}
+
+// UnlockAccount is a wrapper around the personal.unlockAccount RPC method that
+// uses a non-echoing password prompt to acquire the passphrase and executes the
+// original RPC method (saved in jeth.unlockAccount) with it to actually execute
+// the RPC call.
+func (b *bridge) UnlockAccount(call otto.FunctionCall) (response otto.Value) {
+ // Make sure we have an account specified to unlock
+ if !call.Argument(0).IsString() {
+ throwJSException("first argument must be the account to unlock")
+ }
+ account := call.Argument(0)
+
+ // If password is not given or is the null value, prompt the user for it
+ var passwd otto.Value
+
+ if call.Argument(1).IsUndefined() || call.Argument(1).IsNull() {
+ fmt.Fprintf(b.printer, "Unlock account %s\n", account)
+ if input, err := b.prompter.PromptPassword("Passphrase: "); err != nil {
+ throwJSException(err.Error())
+ } else {
+ passwd, _ = otto.ToValue(input)
+ }
+ } else {
+ if !call.Argument(1).IsString() {
+ throwJSException("password must be a string")
+ }
+ passwd = call.Argument(1)
+ }
+ // Third argument is the duration how long the account must be unlocked.
+ duration := otto.NullValue()
+ if call.Argument(2).IsDefined() && !call.Argument(2).IsNull() {
+ if !call.Argument(2).IsNumber() {
+ throwJSException("unlock duration must be a number")
+ }
+ duration = call.Argument(2)
+ }
+ // Send the request to the backend and return
+ val, err := call.Otto.Call("jeth.unlockAccount", nil, account, passwd, duration)
+ if err != nil {
+ throwJSException(err.Error())
+ }
+ return val
+}
+
+// Sign is a wrapper around the personal.sign RPC method that uses a non-echoing password
+// prompt to acquire the passphrase and executes the original RPC method (saved in
+// jeth.sign) with it to actually execute the RPC call.
+func (b *bridge) Sign(call otto.FunctionCall) (response otto.Value) {
+ var (
+ message = call.Argument(0)
+ account = call.Argument(1)
+ passwd = call.Argument(2)
+ )
+
+ if !message.IsString() {
+ throwJSException("first argument must be the message to sign")
+ }
+ if !account.IsString() {
+ throwJSException("second argument must be the account to sign with")
+ }
+
+ // if the password is not given or null ask the user and ensure password is a string
+ if passwd.IsUndefined() || passwd.IsNull() {
+ fmt.Fprintf(b.printer, "Give password for account %s\n", account)
+ if input, err := b.prompter.PromptPassword("Passphrase: "); err != nil {
+ throwJSException(err.Error())
+ } else {
+ passwd, _ = otto.ToValue(input)
+ }
+ }
+ if !passwd.IsString() {
+ throwJSException("third argument must be the password to unlock the account")
+ }
+
+ // Send the request to the backend and return
+ val, err := call.Otto.Call("jeth.sign", nil, message, account, passwd)
+ if err != nil {
+ throwJSException(err.Error())
+ }
+ return val
+}
+
+// Sleep will block the console for the specified number of seconds.
+func (b *bridge) Sleep(call otto.FunctionCall) (response otto.Value) {
+ if call.Argument(0).IsNumber() {
+ sleep, _ := call.Argument(0).ToInteger()
+ time.Sleep(time.Duration(sleep) * time.Second)
+ return otto.TrueValue()
+ }
+ return throwJSException("usage: sleep()")
+}
+
+// SleepBlocks will block the console for a specified number of new blocks optionally
+// until the given timeout is reached.
+func (b *bridge) SleepBlocks(call otto.FunctionCall) (response otto.Value) {
+ var (
+ blocks = int64(0)
+ sleep = int64(9999999999999999) // indefinitely
+ )
+ // Parse the input parameters for the sleep
+ nArgs := len(call.ArgumentList)
+ if nArgs == 0 {
+ throwJSException("usage: sleepBlocks([, max sleep in seconds])")
+ }
+ if nArgs >= 1 {
+ if call.Argument(0).IsNumber() {
+ blocks, _ = call.Argument(0).ToInteger()
+ } else {
+ throwJSException("expected number as first argument")
+ }
+ }
+ if nArgs >= 2 {
+ if call.Argument(1).IsNumber() {
+ sleep, _ = call.Argument(1).ToInteger()
+ } else {
+ throwJSException("expected number as second argument")
+ }
+ }
+ // go through the console, this will allow web3 to call the appropriate
+ // callbacks if a delayed response or notification is received.
+ blockNumber := func() int64 {
+ result, err := call.Otto.Run("eth.blockNumber")
+ if err != nil {
+ throwJSException(err.Error())
+ }
+ block, err := result.ToInteger()
+ if err != nil {
+ throwJSException(err.Error())
+ }
+ return block
+ }
+ // Poll the current block number until either it ot a timeout is reached
+ targetBlockNr := blockNumber() + blocks
+ deadline := time.Now().Add(time.Duration(sleep) * time.Second)
+
+ for time.Now().Before(deadline) {
+ if blockNumber() >= targetBlockNr {
+ return otto.TrueValue()
+ }
+ time.Sleep(time.Second)
+ }
+ return otto.FalseValue()
+}
+
+type jsonrpcCall struct {
+ ID int64
+ Method string
+ Params []interface{}
+}
+
+// Send implements the web3 provider "send" method.
+func (b *bridge) Send(call otto.FunctionCall) (response otto.Value) {
+ // Remarshal the request into a Go value.
+ JSON, _ := call.Otto.Object("JSON")
+ reqVal, err := JSON.Call("stringify", call.Argument(0))
+ if err != nil {
+ throwJSException(err.Error())
+ }
+ var (
+ rawReq = reqVal.String()
+ dec = json.NewDecoder(strings.NewReader(rawReq))
+ reqs []jsonrpcCall
+ batch bool
+ )
+ dec.UseNumber() // avoid float64s
+ if rawReq[0] == '[' {
+ batch = true
+ dec.Decode(&reqs)
+ } else {
+ batch = false
+ reqs = make([]jsonrpcCall, 1)
+ dec.Decode(&reqs[0])
+ }
+
+ // Execute the requests.
+ resps, _ := call.Otto.Object("new Array()")
+ for _, req := range reqs {
+ resp, _ := call.Otto.Object(`({"jsonrpc":"2.0"})`)
+ resp.Set("id", req.ID)
+ var result json.RawMessage
+ err = b.client.Call(&result, req.Method, req.Params...)
+ switch err := err.(type) {
+ case nil:
+ if result == nil {
+ // Special case null because it is decoded as an empty
+ // raw message for some reason.
+ resp.Set("result", otto.NullValue())
+ } else {
+ resultVal, err := JSON.Call("parse", string(result))
+ if err != nil {
+ setError(resp, -32603, err.Error())
+ } else {
+ resp.Set("result", resultVal)
+ }
+ }
+ case rpc.Error:
+ setError(resp, err.ErrorCode(), err.Error())
+ default:
+ setError(resp, -32603, err.Error())
+ }
+ resps.Call("push", resp)
+ }
+
+ // Return the responses either to the callback (if supplied)
+ // or directly as the return value.
+ if batch {
+ response = resps.Value()
+ } else {
+ response, _ = resps.Get("0")
+ }
+ if fn := call.Argument(1); fn.Class() == "Function" {
+ fn.Call(otto.NullValue(), otto.NullValue(), response)
+ return otto.UndefinedValue()
+ }
+ return response
+}
+
+func setError(resp *otto.Object, code int, msg string) {
+ resp.Set("error", map[string]interface{}{"code": code, "message": msg})
+}
+
+// throwJSException panics on an otto.Value. The Otto VM will recover from the
+// Go panic and throw msg as a JavaScript error.
+func throwJSException(msg interface{}) otto.Value {
+ val, err := otto.ToValue(msg)
+ if err != nil {
+ log.Error("Failed to serialize JavaScript exception", "exception", msg, "err", err)
+ }
+ panic(val)
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/console/console.go b/vendor/github.com/ethereum/go-ethereum/console/console.go
new file mode 100644
index 00000000..5326ed2c
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/console/console.go
@@ -0,0 +1,450 @@
+// Copyright 2016 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+package console
+
+import (
+ "fmt"
+ "io"
+ "io/ioutil"
+ "os"
+ "os/signal"
+ "path/filepath"
+ "regexp"
+ "sort"
+ "strings"
+ "syscall"
+
+ "github.com/ethereum/go-ethereum/internal/jsre"
+ "github.com/ethereum/go-ethereum/internal/web3ext"
+ "github.com/ethereum/go-ethereum/rpc"
+ "github.com/mattn/go-colorable"
+ "github.com/peterh/liner"
+ "github.com/robertkrimen/otto"
+)
+
+var (
+ passwordRegexp = regexp.MustCompile(`personal.[nus]`)
+ onlyWhitespace = regexp.MustCompile(`^\s*$`)
+ exit = regexp.MustCompile(`^\s*exit\s*;*\s*$`)
+)
+
+// HistoryFile is the file within the data directory to store input scrollback.
+const HistoryFile = "history"
+
+// DefaultPrompt is the default prompt line prefix to use for user input querying.
+const DefaultPrompt = "> "
+
+// Config is the collection of configurations to fine tune the behavior of the
+// JavaScript console.
+type Config struct {
+ DataDir string // Data directory to store the console history at
+ DocRoot string // Filesystem path from where to load JavaScript files from
+ Client *rpc.Client // RPC client to execute Ethereum requests through
+ Prompt string // Input prompt prefix string (defaults to DefaultPrompt)
+ Prompter UserPrompter // Input prompter to allow interactive user feedback (defaults to TerminalPrompter)
+ Printer io.Writer // Output writer to serialize any display strings to (defaults to os.Stdout)
+ Preload []string // Absolute paths to JavaScript files to preload
+}
+
+// Console is a JavaScript interpreted runtime environment. It is a fully fledged
+// JavaScript console attached to a running node via an external or in-process RPC
+// client.
+type Console struct {
+ client *rpc.Client // RPC client to execute Ethereum requests through
+ jsre *jsre.JSRE // JavaScript runtime environment running the interpreter
+ prompt string // Input prompt prefix string
+ prompter UserPrompter // Input prompter to allow interactive user feedback
+ histPath string // Absolute path to the console scrollback history
+ history []string // Scroll history maintained by the console
+ printer io.Writer // Output writer to serialize any display strings to
+}
+
+// New initializes a JavaScript interpreted runtime environment and sets defaults
+// with the config struct.
+func New(config Config) (*Console, error) {
+ // Handle unset config values gracefully
+ if config.Prompter == nil {
+ config.Prompter = Stdin
+ }
+ if config.Prompt == "" {
+ config.Prompt = DefaultPrompt
+ }
+ if config.Printer == nil {
+ config.Printer = colorable.NewColorableStdout()
+ }
+ // Initialize the console and return
+ console := &Console{
+ client: config.Client,
+ jsre: jsre.New(config.DocRoot, config.Printer),
+ prompt: config.Prompt,
+ prompter: config.Prompter,
+ printer: config.Printer,
+ histPath: filepath.Join(config.DataDir, HistoryFile),
+ }
+ if err := os.MkdirAll(config.DataDir, 0700); err != nil {
+ return nil, err
+ }
+ if err := console.init(config.Preload); err != nil {
+ return nil, err
+ }
+ return console, nil
+}
+
+// init retrieves the available APIs from the remote RPC provider and initializes
+// the console's JavaScript namespaces based on the exposed modules.
+func (c *Console) init(preload []string) error {
+ // Initialize the JavaScript <-> Go RPC bridge
+ bridge := newBridge(c.client, c.prompter, c.printer)
+ c.jsre.Set("jeth", struct{}{})
+
+ jethObj, _ := c.jsre.Get("jeth")
+ jethObj.Object().Set("send", bridge.Send)
+ jethObj.Object().Set("sendAsync", bridge.Send)
+
+ consoleObj, _ := c.jsre.Get("console")
+ consoleObj.Object().Set("log", c.consoleOutput)
+ consoleObj.Object().Set("error", c.consoleOutput)
+
+ // Load all the internal utility JavaScript libraries
+ if err := c.jsre.Compile("bignumber.js", jsre.BignumberJs); err != nil {
+ return fmt.Errorf("bignumber.js: %v", err)
+ }
+ if err := c.jsre.Compile("web3.js", jsre.Web3Js); err != nil {
+ return fmt.Errorf("web3.js: %v", err)
+ }
+ if _, err := c.jsre.Run("var Web3 = require('web3');"); err != nil {
+ return fmt.Errorf("web3 require: %v", err)
+ }
+ if _, err := c.jsre.Run("var web3 = new Web3(jeth);"); err != nil {
+ return fmt.Errorf("web3 provider: %v", err)
+ }
+ // Load the supported APIs into the JavaScript runtime environment
+ apis, err := c.client.SupportedModules()
+ if err != nil {
+ return fmt.Errorf("api modules: %v", err)
+ }
+ flatten := "var eth = web3.eth; var personal = web3.personal; "
+ for api := range apis {
+ if api == "web3" {
+ continue // manually mapped or ignore
+ }
+ if file, ok := web3ext.Modules[api]; ok {
+ // Load our extension for the module.
+ if err = c.jsre.Compile(fmt.Sprintf("%s.js", api), file); err != nil {
+ return fmt.Errorf("%s.js: %v", api, err)
+ }
+ flatten += fmt.Sprintf("var %s = web3.%s; ", api, api)
+ } else if obj, err := c.jsre.Run("web3." + api); err == nil && obj.IsObject() {
+ // Enable web3.js built-in extension if available.
+ flatten += fmt.Sprintf("var %s = web3.%s; ", api, api)
+ }
+ }
+ if _, err = c.jsre.Run(flatten); err != nil {
+ return fmt.Errorf("namespace flattening: %v", err)
+ }
+ // Initialize the global name register (disabled for now)
+ //c.jsre.Run(`var GlobalRegistrar = eth.contract(` + registrar.GlobalRegistrarAbi + `); registrar = GlobalRegistrar.at("` + registrar.GlobalRegistrarAddr + `");`)
+
+ // If the console is in interactive mode, instrument password related methods to query the user
+ if c.prompter != nil {
+ // Retrieve the account management object to instrument
+ personal, err := c.jsre.Get("personal")
+ if err != nil {
+ return err
+ }
+ // Override the openWallet, unlockAccount, newAccount and sign methods since
+ // these require user interaction. Assign these method in the Console the
+ // original web3 callbacks. These will be called by the jeth.* methods after
+ // they got the password from the user and send the original web3 request to
+ // the backend.
+ if obj := personal.Object(); obj != nil { // make sure the personal api is enabled over the interface
+ if _, err = c.jsre.Run(`jeth.openWallet = personal.openWallet;`); err != nil {
+ return fmt.Errorf("personal.openWallet: %v", err)
+ }
+ if _, err = c.jsre.Run(`jeth.unlockAccount = personal.unlockAccount;`); err != nil {
+ return fmt.Errorf("personal.unlockAccount: %v", err)
+ }
+ if _, err = c.jsre.Run(`jeth.newAccount = personal.newAccount;`); err != nil {
+ return fmt.Errorf("personal.newAccount: %v", err)
+ }
+ if _, err = c.jsre.Run(`jeth.sign = personal.sign;`); err != nil {
+ return fmt.Errorf("personal.sign: %v", err)
+ }
+ obj.Set("openWallet", bridge.OpenWallet)
+ obj.Set("unlockAccount", bridge.UnlockAccount)
+ obj.Set("newAccount", bridge.NewAccount)
+ obj.Set("sign", bridge.Sign)
+ }
+ }
+ // The admin.sleep and admin.sleepBlocks are offered by the console and not by the RPC layer.
+ admin, err := c.jsre.Get("admin")
+ if err != nil {
+ return err
+ }
+ if obj := admin.Object(); obj != nil { // make sure the admin api is enabled over the interface
+ obj.Set("sleepBlocks", bridge.SleepBlocks)
+ obj.Set("sleep", bridge.Sleep)
+ obj.Set("clearHistory", c.clearHistory)
+ }
+ // Preload any JavaScript files before starting the console
+ for _, path := range preload {
+ if err := c.jsre.Exec(path); err != nil {
+ failure := err.Error()
+ if ottoErr, ok := err.(*otto.Error); ok {
+ failure = ottoErr.String()
+ }
+ return fmt.Errorf("%s: %v", path, failure)
+ }
+ }
+ // Configure the console's input prompter for scrollback and tab completion
+ if c.prompter != nil {
+ if content, err := ioutil.ReadFile(c.histPath); err != nil {
+ c.prompter.SetHistory(nil)
+ } else {
+ c.history = strings.Split(string(content), "\n")
+ c.prompter.SetHistory(c.history)
+ }
+ c.prompter.SetWordCompleter(c.AutoCompleteInput)
+ }
+ return nil
+}
+
+func (c *Console) clearHistory() {
+ c.history = nil
+ c.prompter.ClearHistory()
+ if err := os.Remove(c.histPath); err != nil {
+ fmt.Fprintln(c.printer, "can't delete history file:", err)
+ } else {
+ fmt.Fprintln(c.printer, "history file deleted")
+ }
+}
+
+// consoleOutput is an override for the console.log and console.error methods to
+// stream the output into the configured output stream instead of stdout.
+func (c *Console) consoleOutput(call otto.FunctionCall) otto.Value {
+ var output []string
+ for _, argument := range call.ArgumentList {
+ output = append(output, fmt.Sprintf("%v", argument))
+ }
+ fmt.Fprintln(c.printer, strings.Join(output, " "))
+ return otto.Value{}
+}
+
+// AutoCompleteInput is a pre-assembled word completer to be used by the user
+// input prompter to provide hints to the user about the methods available.
+func (c *Console) AutoCompleteInput(line string, pos int) (string, []string, string) {
+ // No completions can be provided for empty inputs
+ if len(line) == 0 || pos == 0 {
+ return "", nil, ""
+ }
+ // Chunck data to relevant part for autocompletion
+ // E.g. in case of nested lines eth.getBalance(eth.coinb
+ start := pos - 1
+ for ; start > 0; start-- {
+ // Skip all methods and namespaces (i.e. including the dot)
+ if line[start] == '.' || (line[start] >= 'a' && line[start] <= 'z') || (line[start] >= 'A' && line[start] <= 'Z') {
+ continue
+ }
+ // Handle web3 in a special way (i.e. other numbers aren't auto completed)
+ if start >= 3 && line[start-3:start] == "web3" {
+ start -= 3
+ continue
+ }
+ // We've hit an unexpected character, autocomplete form here
+ start++
+ break
+ }
+ return line[:start], c.jsre.CompleteKeywords(line[start:pos]), line[pos:]
+}
+
+// Welcome show summary of current Geth instance and some metadata about the
+// console's available modules.
+func (c *Console) Welcome() {
+ message := "Welcome to the Geth JavaScript console!\n\n"
+
+ // Print some generic Geth metadata
+ if res, err := c.jsre.Run(`
+ var message = "instance: " + web3.version.node + "\n";
+ try {
+ message += "coinbase: " + eth.coinbase + "\n";
+ } catch (err) {}
+ message += "at block: " + eth.blockNumber + " (" + new Date(1000 * eth.getBlock(eth.blockNumber).timestamp) + ")\n";
+ try {
+ message += " datadir: " + admin.datadir + "\n";
+ } catch (err) {}
+ message
+ `); err == nil {
+ message += res.String()
+ }
+ // List all the supported modules for the user to call
+ if apis, err := c.client.SupportedModules(); err == nil {
+ modules := make([]string, 0, len(apis))
+ for api, version := range apis {
+ modules = append(modules, fmt.Sprintf("%s:%s", api, version))
+ }
+ sort.Strings(modules)
+ message += " modules: " + strings.Join(modules, " ") + "\n"
+ }
+ fmt.Fprintln(c.printer, message)
+}
+
+// Evaluate executes code and pretty prints the result to the specified output
+// stream.
+func (c *Console) Evaluate(statement string) error {
+ defer func() {
+ if r := recover(); r != nil {
+ fmt.Fprintf(c.printer, "[native] error: %v\n", r)
+ }
+ }()
+ return c.jsre.Evaluate(statement, c.printer)
+}
+
+// Interactive starts an interactive user session, where input is propted from
+// the configured user prompter.
+func (c *Console) Interactive() {
+ var (
+ prompt = c.prompt // Current prompt line (used for multi-line inputs)
+ indents = 0 // Current number of input indents (used for multi-line inputs)
+ input = "" // Current user input
+ scheduler = make(chan string) // Channel to send the next prompt on and receive the input
+ )
+ // Start a goroutine to listen for prompt requests and send back inputs
+ go func() {
+ for {
+ // Read the next user input
+ line, err := c.prompter.PromptInput(<-scheduler)
+ if err != nil {
+ // In case of an error, either clear the prompt or fail
+ if err == liner.ErrPromptAborted { // ctrl-C
+ prompt, indents, input = c.prompt, 0, ""
+ scheduler <- ""
+ continue
+ }
+ close(scheduler)
+ return
+ }
+ // User input retrieved, send for interpretation and loop
+ scheduler <- line
+ }
+ }()
+ // Monitor Ctrl-C too in case the input is empty and we need to bail
+ abort := make(chan os.Signal, 1)
+ signal.Notify(abort, syscall.SIGINT, syscall.SIGTERM)
+
+ // Start sending prompts to the user and reading back inputs
+ for {
+ // Send the next prompt, triggering an input read and process the result
+ scheduler <- prompt
+ select {
+ case <-abort:
+ // User forcefully quite the console
+ fmt.Fprintln(c.printer, "caught interrupt, exiting")
+ return
+
+ case line, ok := <-scheduler:
+ // User input was returned by the prompter, handle special cases
+ if !ok || (indents <= 0 && exit.MatchString(line)) {
+ return
+ }
+ if onlyWhitespace.MatchString(line) {
+ continue
+ }
+ // Append the line to the input and check for multi-line interpretation
+ input += line + "\n"
+
+ indents = countIndents(input)
+ if indents <= 0 {
+ prompt = c.prompt
+ } else {
+ prompt = strings.Repeat(".", indents*3) + " "
+ }
+ // If all the needed lines are present, save the command and run
+ if indents <= 0 {
+ if len(input) > 0 && input[0] != ' ' && !passwordRegexp.MatchString(input) {
+ if command := strings.TrimSpace(input); len(c.history) == 0 || command != c.history[len(c.history)-1] {
+ c.history = append(c.history, command)
+ if c.prompter != nil {
+ c.prompter.AppendHistory(command)
+ }
+ }
+ }
+ c.Evaluate(input)
+ input = ""
+ }
+ }
+ }
+}
+
+// countIndents returns the number of identations for the given input.
+// In case of invalid input such as var a = } the result can be negative.
+func countIndents(input string) int {
+ var (
+ indents = 0
+ inString = false
+ strOpenChar = ' ' // keep track of the string open char to allow var str = "I'm ....";
+ charEscaped = false // keep track if the previous char was the '\' char, allow var str = "abc\"def";
+ )
+
+ for _, c := range input {
+ switch c {
+ case '\\':
+ // indicate next char as escaped when in string and previous char isn't escaping this backslash
+ if !charEscaped && inString {
+ charEscaped = true
+ }
+ case '\'', '"':
+ if inString && !charEscaped && strOpenChar == c { // end string
+ inString = false
+ } else if !inString && !charEscaped { // begin string
+ inString = true
+ strOpenChar = c
+ }
+ charEscaped = false
+ case '{', '(':
+ if !inString { // ignore brackets when in string, allow var str = "a{"; without indenting
+ indents++
+ }
+ charEscaped = false
+ case '}', ')':
+ if !inString {
+ indents--
+ }
+ charEscaped = false
+ default:
+ charEscaped = false
+ }
+ }
+
+ return indents
+}
+
+// Execute runs the JavaScript file specified as the argument.
+func (c *Console) Execute(path string) error {
+ return c.jsre.Exec(path)
+}
+
+// Stop cleans up the console and terminates the runtime environment.
+func (c *Console) Stop(graceful bool) error {
+ if err := ioutil.WriteFile(c.histPath, []byte(strings.Join(c.history, "\n")), 0600); err != nil {
+ return err
+ }
+ if err := os.Chmod(c.histPath, 0600); err != nil { // Force 0600, even if it was different previously
+ return err
+ }
+ c.jsre.Stop(graceful)
+ return nil
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/console/prompter.go b/vendor/github.com/ethereum/go-ethereum/console/prompter.go
new file mode 100644
index 00000000..29a53aea
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/console/prompter.go
@@ -0,0 +1,172 @@
+// Copyright 2016 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+package console
+
+import (
+ "fmt"
+ "strings"
+
+ "github.com/peterh/liner"
+)
+
+// Stdin holds the stdin line reader (also using stdout for printing prompts).
+// Only this reader may be used for input because it keeps an internal buffer.
+var Stdin = newTerminalPrompter()
+
+// UserPrompter defines the methods needed by the console to prompt the user for
+// various types of inputs.
+type UserPrompter interface {
+ // PromptInput displays the given prompt to the user and requests some textual
+ // data to be entered, returning the input of the user.
+ PromptInput(prompt string) (string, error)
+
+ // PromptPassword displays the given prompt to the user and requests some textual
+ // data to be entered, but one which must not be echoed out into the terminal.
+ // The method returns the input provided by the user.
+ PromptPassword(prompt string) (string, error)
+
+ // PromptConfirm displays the given prompt to the user and requests a boolean
+ // choice to be made, returning that choice.
+ PromptConfirm(prompt string) (bool, error)
+
+ // SetHistory sets the input scrollback history that the prompter will allow
+ // the user to scroll back to.
+ SetHistory(history []string)
+
+ // AppendHistory appends an entry to the scrollback history. It should be called
+ // if and only if the prompt to append was a valid command.
+ AppendHistory(command string)
+
+ // ClearHistory clears the entire history
+ ClearHistory()
+
+ // SetWordCompleter sets the completion function that the prompter will call to
+ // fetch completion candidates when the user presses tab.
+ SetWordCompleter(completer WordCompleter)
+}
+
+// WordCompleter takes the currently edited line with the cursor position and
+// returns the completion candidates for the partial word to be completed. If
+// the line is "Hello, wo!!!" and the cursor is before the first '!', ("Hello,
+// wo!!!", 9) is passed to the completer which may returns ("Hello, ", {"world",
+// "Word"}, "!!!") to have "Hello, world!!!".
+type WordCompleter func(line string, pos int) (string, []string, string)
+
+// terminalPrompter is a UserPrompter backed by the liner package. It supports
+// prompting the user for various input, among others for non-echoing password
+// input.
+type terminalPrompter struct {
+ *liner.State
+ warned bool
+ supported bool
+ normalMode liner.ModeApplier
+ rawMode liner.ModeApplier
+}
+
+// newTerminalPrompter creates a liner based user input prompter working off the
+// standard input and output streams.
+func newTerminalPrompter() *terminalPrompter {
+ p := new(terminalPrompter)
+ // Get the original mode before calling NewLiner.
+ // This is usually regular "cooked" mode where characters echo.
+ normalMode, _ := liner.TerminalMode()
+ // Turn on liner. It switches to raw mode.
+ p.State = liner.NewLiner()
+ rawMode, err := liner.TerminalMode()
+ if err != nil || !liner.TerminalSupported() {
+ p.supported = false
+ } else {
+ p.supported = true
+ p.normalMode = normalMode
+ p.rawMode = rawMode
+ // Switch back to normal mode while we're not prompting.
+ normalMode.ApplyMode()
+ }
+ p.SetCtrlCAborts(true)
+ p.SetTabCompletionStyle(liner.TabPrints)
+ p.SetMultiLineMode(true)
+ return p
+}
+
+// PromptInput displays the given prompt to the user and requests some textual
+// data to be entered, returning the input of the user.
+func (p *terminalPrompter) PromptInput(prompt string) (string, error) {
+ if p.supported {
+ p.rawMode.ApplyMode()
+ defer p.normalMode.ApplyMode()
+ } else {
+ // liner tries to be smart about printing the prompt
+ // and doesn't print anything if input is redirected.
+ // Un-smart it by printing the prompt always.
+ fmt.Print(prompt)
+ prompt = ""
+ defer fmt.Println()
+ }
+ return p.State.Prompt(prompt)
+}
+
+// PromptPassword displays the given prompt to the user and requests some textual
+// data to be entered, but one which must not be echoed out into the terminal.
+// The method returns the input provided by the user.
+func (p *terminalPrompter) PromptPassword(prompt string) (passwd string, err error) {
+ if p.supported {
+ p.rawMode.ApplyMode()
+ defer p.normalMode.ApplyMode()
+ return p.State.PasswordPrompt(prompt)
+ }
+ if !p.warned {
+ fmt.Println("!! Unsupported terminal, password will be echoed.")
+ p.warned = true
+ }
+ // Just as in Prompt, handle printing the prompt here instead of relying on liner.
+ fmt.Print(prompt)
+ passwd, err = p.State.Prompt("")
+ fmt.Println()
+ return passwd, err
+}
+
+// PromptConfirm displays the given prompt to the user and requests a boolean
+// choice to be made, returning that choice.
+func (p *terminalPrompter) PromptConfirm(prompt string) (bool, error) {
+ input, err := p.Prompt(prompt + " [y/N] ")
+ if len(input) > 0 && strings.ToUpper(input[:1]) == "Y" {
+ return true, nil
+ }
+ return false, err
+}
+
+// SetHistory sets the input scrollback history that the prompter will allow
+// the user to scroll back to.
+func (p *terminalPrompter) SetHistory(history []string) {
+ p.State.ReadHistory(strings.NewReader(strings.Join(history, "\n")))
+}
+
+// AppendHistory appends an entry to the scrollback history.
+func (p *terminalPrompter) AppendHistory(command string) {
+ p.State.AppendHistory(command)
+}
+
+// ClearHistory clears the entire history
+func (p *terminalPrompter) ClearHistory() {
+ p.State.ClearHistory()
+}
+
+// SetWordCompleter sets the completion function that the prompter will call to
+// fetch completion candidates when the user presses tab.
+func (p *terminalPrompter) SetWordCompleter(completer WordCompleter) {
+ p.State.SetWordCompleter(liner.WordCompleter(completer))
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/console/testdata/exec.js b/vendor/github.com/ethereum/go-ethereum/console/testdata/exec.js
new file mode 100644
index 00000000..59e34d7c
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/console/testdata/exec.js
@@ -0,0 +1 @@
+var execed = "some-executed-string";
diff --git a/vendor/github.com/ethereum/go-ethereum/console/testdata/preload.js b/vendor/github.com/ethereum/go-ethereum/console/testdata/preload.js
new file mode 100644
index 00000000..55679397
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/console/testdata/preload.js
@@ -0,0 +1 @@
+var preloaded = "some-preloaded-string";
diff --git a/vendor/github.com/ethereum/go-ethereum/contracts/chequebook/api.go b/vendor/github.com/ethereum/go-ethereum/contracts/chequebook/api.go
new file mode 100644
index 00000000..fb708030
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/contracts/chequebook/api.go
@@ -0,0 +1,68 @@
+// Copyright 2016 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+package chequebook
+
+import (
+ "errors"
+ "math/big"
+
+ "github.com/ethereum/go-ethereum/common"
+)
+
+const Version = "1.0"
+
+var errNoChequebook = errors.New("no chequebook")
+
+type API struct {
+ chequebookf func() *Chequebook
+}
+
+func NewAPI(ch func() *Chequebook) *API {
+ return &API{ch}
+}
+
+func (a *API) Balance() (string, error) {
+ ch := a.chequebookf()
+ if ch == nil {
+ return "", errNoChequebook
+ }
+ return ch.Balance().String(), nil
+}
+
+func (a *API) Issue(beneficiary common.Address, amount *big.Int) (cheque *Cheque, err error) {
+ ch := a.chequebookf()
+ if ch == nil {
+ return nil, errNoChequebook
+ }
+ return ch.Issue(beneficiary, amount)
+}
+
+func (a *API) Cash(cheque *Cheque) (txhash string, err error) {
+ ch := a.chequebookf()
+ if ch == nil {
+ return "", errNoChequebook
+ }
+ return ch.Cash(cheque)
+}
+
+func (a *API) Deposit(amount *big.Int) (txhash string, err error) {
+ ch := a.chequebookf()
+ if ch == nil {
+ return "", errNoChequebook
+ }
+ return ch.Deposit(amount)
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/contracts/chequebook/cheque.go b/vendor/github.com/ethereum/go-ethereum/contracts/chequebook/cheque.go
new file mode 100644
index 00000000..32e84067
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/contracts/chequebook/cheque.go
@@ -0,0 +1,642 @@
+// Copyright 2016 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+// Package chequebook package wraps the 'chequebook' Ethereum smart contract.
+//
+// The functions in this package allow using chequebook for
+// issuing, receiving, verifying cheques in ether; (auto)cashing cheques in ether
+// as well as (auto)depositing ether to the chequebook contract.
+package chequebook
+
+//go:generate abigen --sol contract/chequebook.sol --exc contract/mortal.sol:mortal,contract/owned.sol:owned --pkg contract --out contract/chequebook.go
+//go:generate go run ./gencode.go
+
+import (
+ "bytes"
+ "context"
+ "crypto/ecdsa"
+ "encoding/json"
+ "fmt"
+ "io/ioutil"
+ "math/big"
+ "os"
+ "sync"
+ "time"
+
+ "github.com/ethereum/go-ethereum/accounts/abi/bind"
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/common/hexutil"
+ "github.com/ethereum/go-ethereum/contracts/chequebook/contract"
+ "github.com/ethereum/go-ethereum/core/types"
+ "github.com/ethereum/go-ethereum/crypto"
+ "github.com/ethereum/go-ethereum/log"
+ "github.com/ethereum/go-ethereum/swarm/services/swap/swap"
+)
+
+// TODO(zelig): watch peer solvency and notify of bouncing cheques
+// TODO(zelig): enable paying with cheque by signing off
+
+// Some functionality requires interacting with the blockchain:
+// * setting current balance on peer's chequebook
+// * sending the transaction to cash the cheque
+// * depositing ether to the chequebook
+// * watching incoming ether
+
+var (
+ gasToCash = uint64(2000000) // gas cost of a cash transaction using chequebook
+ // gasToDeploy = uint64(3000000)
+)
+
+// Backend wraps all methods required for chequebook operation.
+type Backend interface {
+ bind.ContractBackend
+ TransactionReceipt(ctx context.Context, txHash common.Hash) (*types.Receipt, error)
+ BalanceAt(ctx context.Context, address common.Address, blockNum *big.Int) (*big.Int, error)
+}
+
+// Cheque represents a payment promise to a single beneficiary.
+type Cheque struct {
+ Contract common.Address // address of chequebook, needed to avoid cross-contract submission
+ Beneficiary common.Address
+ Amount *big.Int // cumulative amount of all funds sent
+ Sig []byte // signature Sign(Keccak256(contract, beneficiary, amount), prvKey)
+}
+
+func (ch *Cheque) String() string {
+ return fmt.Sprintf("contract: %s, beneficiary: %s, amount: %v, signature: %x", ch.Contract.Hex(), ch.Beneficiary.Hex(), ch.Amount, ch.Sig)
+}
+
+type Params struct {
+ ContractCode, ContractAbi string
+}
+
+var ContractParams = &Params{contract.ChequebookBin, contract.ChequebookABI}
+
+// Chequebook can create and sign cheques from a single contract to multiple beneficiaries.
+// It is the outgoing payment handler for peer to peer micropayments.
+type Chequebook struct {
+ path string // path to chequebook file
+ prvKey *ecdsa.PrivateKey // private key to sign cheque with
+ lock sync.Mutex //
+ backend Backend // blockchain API
+ quit chan bool // when closed causes autodeposit to stop
+ owner common.Address // owner address (derived from pubkey)
+ contract *contract.Chequebook // abigen binding
+ session *contract.ChequebookSession // abigen binding with Tx Opts
+
+ // persisted fields
+ balance *big.Int // not synced with blockchain
+ contractAddr common.Address // contract address
+ sent map[common.Address]*big.Int //tallies for beneficiaries
+
+ txhash string // tx hash of last deposit tx
+ threshold *big.Int // threshold that triggers autodeposit if not nil
+ buffer *big.Int // buffer to keep on top of balance for fork protection
+
+ log log.Logger // contextual logger with the contract address embedded
+}
+
+func (cb *Chequebook) String() string {
+ return fmt.Sprintf("contract: %s, owner: %s, balance: %v, signer: %x", cb.contractAddr.Hex(), cb.owner.Hex(), cb.balance, cb.prvKey.PublicKey)
+}
+
+// NewChequebook creates a new Chequebook.
+func NewChequebook(path string, contractAddr common.Address, prvKey *ecdsa.PrivateKey, backend Backend) (*Chequebook, error) {
+ balance := new(big.Int)
+ sent := make(map[common.Address]*big.Int)
+
+ chbook, err := contract.NewChequebook(contractAddr, backend)
+ if err != nil {
+ return nil, err
+ }
+ transactOpts := bind.NewKeyedTransactor(prvKey)
+ session := &contract.ChequebookSession{
+ Contract: chbook,
+ TransactOpts: *transactOpts,
+ }
+
+ cb := &Chequebook{
+ prvKey: prvKey,
+ balance: balance,
+ contractAddr: contractAddr,
+ sent: sent,
+ path: path,
+ backend: backend,
+ owner: transactOpts.From,
+ contract: chbook,
+ session: session,
+ log: log.New("contract", contractAddr),
+ }
+ if (contractAddr != common.Address{}) {
+ cb.setBalanceFromBlockChain()
+ cb.log.Trace("New chequebook initialised", "owner", cb.owner, "balance", cb.balance)
+ }
+ return cb, nil
+}
+
+func (cb *Chequebook) setBalanceFromBlockChain() {
+ balance, err := cb.backend.BalanceAt(context.TODO(), cb.contractAddr, nil)
+ if err != nil {
+ log.Error("Failed to retrieve chequebook balance", "err", err)
+ } else {
+ cb.balance.Set(balance)
+ }
+}
+
+// LoadChequebook loads a chequebook from disk (file path).
+func LoadChequebook(path string, prvKey *ecdsa.PrivateKey, backend Backend, checkBalance bool) (*Chequebook, error) {
+ data, err := ioutil.ReadFile(path)
+ if err != nil {
+ return nil, err
+ }
+ cb, _ := NewChequebook(path, common.Address{}, prvKey, backend)
+
+ if err = json.Unmarshal(data, cb); err != nil {
+ return nil, err
+ }
+ if checkBalance {
+ cb.setBalanceFromBlockChain()
+ }
+ log.Trace("Loaded chequebook from disk", "path", path)
+
+ return cb, nil
+}
+
+// chequebookFile is the JSON representation of a chequebook.
+type chequebookFile struct {
+ Balance string
+ Contract string
+ Owner string
+ Sent map[string]string
+}
+
+// UnmarshalJSON deserialises a chequebook.
+func (cb *Chequebook) UnmarshalJSON(data []byte) error {
+ var file chequebookFile
+ err := json.Unmarshal(data, &file)
+ if err != nil {
+ return err
+ }
+ _, ok := cb.balance.SetString(file.Balance, 10)
+ if !ok {
+ return fmt.Errorf("cumulative amount sent: unable to convert string to big integer: %v", file.Balance)
+ }
+ cb.contractAddr = common.HexToAddress(file.Contract)
+ for addr, sent := range file.Sent {
+ cb.sent[common.HexToAddress(addr)], ok = new(big.Int).SetString(sent, 10)
+ if !ok {
+ return fmt.Errorf("beneficiary %v cumulative amount sent: unable to convert string to big integer: %v", addr, sent)
+ }
+ }
+ return nil
+}
+
+// MarshalJSON serialises a chequebook.
+func (cb *Chequebook) MarshalJSON() ([]byte, error) {
+ var file = &chequebookFile{
+ Balance: cb.balance.String(),
+ Contract: cb.contractAddr.Hex(),
+ Owner: cb.owner.Hex(),
+ Sent: make(map[string]string),
+ }
+ for addr, sent := range cb.sent {
+ file.Sent[addr.Hex()] = sent.String()
+ }
+ return json.Marshal(file)
+}
+
+// Save persists the chequebook on disk, remembering balance, contract address and
+// cumulative amount of funds sent for each beneficiary.
+func (cb *Chequebook) Save() error {
+ data, err := json.MarshalIndent(cb, "", " ")
+ if err != nil {
+ return err
+ }
+ cb.log.Trace("Saving chequebook to disk", cb.path)
+
+ return ioutil.WriteFile(cb.path, data, os.ModePerm)
+}
+
+// Stop quits the autodeposit go routine to terminate
+func (cb *Chequebook) Stop() {
+ defer cb.lock.Unlock()
+ cb.lock.Lock()
+ if cb.quit != nil {
+ close(cb.quit)
+ cb.quit = nil
+ }
+}
+
+// Issue creates a cheque signed by the chequebook owner's private key. The
+// signer commits to a contract (one that they own), a beneficiary and amount.
+func (cb *Chequebook) Issue(beneficiary common.Address, amount *big.Int) (*Cheque, error) {
+ defer cb.lock.Unlock()
+ cb.lock.Lock()
+
+ if amount.Sign() <= 0 {
+ return nil, fmt.Errorf("amount must be greater than zero (%v)", amount)
+ }
+ var (
+ ch *Cheque
+ err error
+ )
+ if cb.balance.Cmp(amount) < 0 {
+ err = fmt.Errorf("insufficient funds to issue cheque for amount: %v. balance: %v", amount, cb.balance)
+ } else {
+ var sig []byte
+ sent, found := cb.sent[beneficiary]
+ if !found {
+ sent = new(big.Int)
+ cb.sent[beneficiary] = sent
+ }
+ sum := new(big.Int).Set(sent)
+ sum.Add(sum, amount)
+
+ sig, err = crypto.Sign(sigHash(cb.contractAddr, beneficiary, sum), cb.prvKey)
+ if err == nil {
+ ch = &Cheque{
+ Contract: cb.contractAddr,
+ Beneficiary: beneficiary,
+ Amount: sum,
+ Sig: sig,
+ }
+ sent.Set(sum)
+ cb.balance.Sub(cb.balance, amount) // subtract amount from balance
+ }
+ }
+ // auto deposit if threshold is set and balance is less then threshold
+ // note this is called even if issuing cheque fails
+ // so we reattempt depositing
+ if cb.threshold != nil {
+ if cb.balance.Cmp(cb.threshold) < 0 {
+ send := new(big.Int).Sub(cb.buffer, cb.balance)
+ cb.deposit(send)
+ }
+ }
+ return ch, err
+}
+
+// Cash is a convenience method to cash any cheque.
+func (cb *Chequebook) Cash(ch *Cheque) (string, error) {
+ return ch.Cash(cb.session)
+}
+
+// data to sign: contract address, beneficiary, cumulative amount of funds ever sent
+func sigHash(contract, beneficiary common.Address, sum *big.Int) []byte {
+ bigamount := sum.Bytes()
+ if len(bigamount) > 32 {
+ return nil
+ }
+ var amount32 [32]byte
+ copy(amount32[32-len(bigamount):32], bigamount)
+ input := append(contract.Bytes(), beneficiary.Bytes()...)
+ input = append(input, amount32[:]...)
+ return crypto.Keccak256(input)
+}
+
+// Balance returns the current balance of the chequebook.
+func (cb *Chequebook) Balance() *big.Int {
+ defer cb.lock.Unlock()
+ cb.lock.Lock()
+ return new(big.Int).Set(cb.balance)
+}
+
+// Owner returns the owner account of the chequebook.
+func (cb *Chequebook) Owner() common.Address {
+ return cb.owner
+}
+
+// Address returns the on-chain contract address of the chequebook.
+func (cb *Chequebook) Address() common.Address {
+ return cb.contractAddr
+}
+
+// Deposit deposits money to the chequebook account.
+func (cb *Chequebook) Deposit(amount *big.Int) (string, error) {
+ defer cb.lock.Unlock()
+ cb.lock.Lock()
+ return cb.deposit(amount)
+}
+
+// deposit deposits amount to the chequebook account.
+// The caller must hold lock.
+func (cb *Chequebook) deposit(amount *big.Int) (string, error) {
+ // since the amount is variable here, we do not use sessions
+ depositTransactor := bind.NewKeyedTransactor(cb.prvKey)
+ depositTransactor.Value = amount
+ chbookRaw := &contract.ChequebookRaw{Contract: cb.contract}
+ tx, err := chbookRaw.Transfer(depositTransactor)
+ if err != nil {
+ cb.log.Warn("Failed to fund chequebook", "amount", amount, "balance", cb.balance, "target", cb.buffer, "err", err)
+ return "", err
+ }
+ // assume that transaction is actually successful, we add the amount to balance right away
+ cb.balance.Add(cb.balance, amount)
+ cb.log.Trace("Deposited funds to chequebook", "amount", amount, "balance", cb.balance, "target", cb.buffer)
+ return tx.Hash().Hex(), nil
+}
+
+// AutoDeposit (re)sets interval time and amount which triggers sending funds to the
+// chequebook. Contract backend needs to be set if threshold is not less than buffer, then
+// deposit will be triggered on every new cheque issued.
+func (cb *Chequebook) AutoDeposit(interval time.Duration, threshold, buffer *big.Int) {
+ defer cb.lock.Unlock()
+ cb.lock.Lock()
+ cb.threshold = threshold
+ cb.buffer = buffer
+ cb.autoDeposit(interval)
+}
+
+// autoDeposit starts a goroutine that periodically sends funds to the chequebook
+// contract caller holds the lock the go routine terminates if Chequebook.quit is closed.
+func (cb *Chequebook) autoDeposit(interval time.Duration) {
+ if cb.quit != nil {
+ close(cb.quit)
+ cb.quit = nil
+ }
+ // if threshold >= balance autodeposit after every cheque issued
+ if interval == time.Duration(0) || cb.threshold != nil && cb.buffer != nil && cb.threshold.Cmp(cb.buffer) >= 0 {
+ return
+ }
+
+ ticker := time.NewTicker(interval)
+ cb.quit = make(chan bool)
+ quit := cb.quit
+
+ go func() {
+ for {
+ select {
+ case <-quit:
+ return
+ case <-ticker.C:
+ cb.lock.Lock()
+ if cb.balance.Cmp(cb.buffer) < 0 {
+ amount := new(big.Int).Sub(cb.buffer, cb.balance)
+ txhash, err := cb.deposit(amount)
+ if err == nil {
+ cb.txhash = txhash
+ }
+ }
+ cb.lock.Unlock()
+ }
+ }
+ }()
+}
+
+// Outbox can issue cheques from a single contract to a single beneficiary.
+type Outbox struct {
+ chequeBook *Chequebook
+ beneficiary common.Address
+}
+
+// NewOutbox creates an outbox.
+func NewOutbox(cb *Chequebook, beneficiary common.Address) *Outbox {
+ return &Outbox{cb, beneficiary}
+}
+
+// Issue creates cheque.
+func (o *Outbox) Issue(amount *big.Int) (swap.Promise, error) {
+ return o.chequeBook.Issue(o.beneficiary, amount)
+}
+
+// AutoDeposit enables auto-deposits on the underlying chequebook.
+func (o *Outbox) AutoDeposit(interval time.Duration, threshold, buffer *big.Int) {
+ o.chequeBook.AutoDeposit(interval, threshold, buffer)
+}
+
+// Stop helps satisfy the swap.OutPayment interface.
+func (o *Outbox) Stop() {}
+
+// String implements fmt.Stringer.
+func (o *Outbox) String() string {
+ return fmt.Sprintf("chequebook: %v, beneficiary: %s, balance: %v", o.chequeBook.Address().Hex(), o.beneficiary.Hex(), o.chequeBook.Balance())
+}
+
+// Inbox can deposit, verify and cash cheques from a single contract to a single
+// beneficiary. It is the incoming payment handler for peer to peer micropayments.
+type Inbox struct {
+ lock sync.Mutex
+ contract common.Address // peer's chequebook contract
+ beneficiary common.Address // local peer's receiving address
+ sender common.Address // local peer's address to send cashing tx from
+ signer *ecdsa.PublicKey // peer's public key
+ txhash string // tx hash of last cashing tx
+ session *contract.ChequebookSession // abi contract backend with tx opts
+ quit chan bool // when closed causes autocash to stop
+ maxUncashed *big.Int // threshold that triggers autocashing
+ cashed *big.Int // cumulative amount cashed
+ cheque *Cheque // last cheque, nil if none yet received
+ log log.Logger // contextual logger with the contract address embedded
+}
+
+// NewInbox creates an Inbox. An Inboxes is not persisted, the cumulative sum is updated
+// from blockchain when first cheque is received.
+func NewInbox(prvKey *ecdsa.PrivateKey, contractAddr, beneficiary common.Address, signer *ecdsa.PublicKey, abigen bind.ContractBackend) (*Inbox, error) {
+ if signer == nil {
+ return nil, fmt.Errorf("signer is null")
+ }
+ chbook, err := contract.NewChequebook(contractAddr, abigen)
+ if err != nil {
+ return nil, err
+ }
+ transactOpts := bind.NewKeyedTransactor(prvKey)
+ transactOpts.GasLimit = gasToCash
+ session := &contract.ChequebookSession{
+ Contract: chbook,
+ TransactOpts: *transactOpts,
+ }
+ sender := transactOpts.From
+
+ inbox := &Inbox{
+ contract: contractAddr,
+ beneficiary: beneficiary,
+ sender: sender,
+ signer: signer,
+ session: session,
+ cashed: new(big.Int).Set(common.Big0),
+ log: log.New("contract", contractAddr),
+ }
+ inbox.log.Trace("New chequebook inbox initialized", "beneficiary", inbox.beneficiary, "signer", hexutil.Bytes(crypto.FromECDSAPub(signer)))
+ return inbox, nil
+}
+
+func (i *Inbox) String() string {
+ return fmt.Sprintf("chequebook: %v, beneficiary: %s, balance: %v", i.contract.Hex(), i.beneficiary.Hex(), i.cheque.Amount)
+}
+
+// Stop quits the autocash goroutine.
+func (i *Inbox) Stop() {
+ defer i.lock.Unlock()
+ i.lock.Lock()
+ if i.quit != nil {
+ close(i.quit)
+ i.quit = nil
+ }
+}
+
+// Cash attempts to cash the current cheque.
+func (i *Inbox) Cash() (string, error) {
+ if i.cheque == nil {
+ return "", nil
+ }
+ txhash, err := i.cheque.Cash(i.session)
+ i.log.Trace("Cashing in chequebook cheque", "amount", i.cheque.Amount, "beneficiary", i.beneficiary)
+ i.cashed = i.cheque.Amount
+
+ return txhash, err
+}
+
+// AutoCash (re)sets maximum time and amount which triggers cashing of the last uncashed
+// cheque if maxUncashed is set to 0, then autocash on receipt.
+func (i *Inbox) AutoCash(cashInterval time.Duration, maxUncashed *big.Int) {
+ defer i.lock.Unlock()
+ i.lock.Lock()
+ i.maxUncashed = maxUncashed
+ i.autoCash(cashInterval)
+}
+
+// autoCash starts a loop that periodically clears the last cheque
+// if the peer is trusted. Clearing period could be 24h or a week.
+// The caller must hold lock.
+func (i *Inbox) autoCash(cashInterval time.Duration) {
+ if i.quit != nil {
+ close(i.quit)
+ i.quit = nil
+ }
+ // if maxUncashed is set to 0, then autocash on receipt
+ if cashInterval == time.Duration(0) || i.maxUncashed != nil && i.maxUncashed.Sign() == 0 {
+ return
+ }
+
+ ticker := time.NewTicker(cashInterval)
+ i.quit = make(chan bool)
+ quit := i.quit
+
+ go func() {
+ for {
+ select {
+ case <-quit:
+ return
+ case <-ticker.C:
+ i.lock.Lock()
+ if i.cheque != nil && i.cheque.Amount.Cmp(i.cashed) != 0 {
+ txhash, err := i.Cash()
+ if err == nil {
+ i.txhash = txhash
+ }
+ }
+ i.lock.Unlock()
+ }
+ }
+ }()
+}
+
+// Receive is called to deposit the latest cheque to the incoming Inbox.
+// The given promise must be a *Cheque.
+func (i *Inbox) Receive(promise swap.Promise) (*big.Int, error) {
+ ch := promise.(*Cheque)
+
+ defer i.lock.Unlock()
+ i.lock.Lock()
+
+ var sum *big.Int
+ if i.cheque == nil {
+ // the sum is checked against the blockchain once a cheque is received
+ tally, err := i.session.Sent(i.beneficiary)
+ if err != nil {
+ return nil, fmt.Errorf("inbox: error calling backend to set amount: %v", err)
+ }
+ sum = tally
+ } else {
+ sum = i.cheque.Amount
+ }
+
+ amount, err := ch.Verify(i.signer, i.contract, i.beneficiary, sum)
+ var uncashed *big.Int
+ if err == nil {
+ i.cheque = ch
+
+ if i.maxUncashed != nil {
+ uncashed = new(big.Int).Sub(ch.Amount, i.cashed)
+ if i.maxUncashed.Cmp(uncashed) < 0 {
+ i.Cash()
+ }
+ }
+ i.log.Trace("Received cheque in chequebook inbox", "amount", amount, "uncashed", uncashed)
+ }
+
+ return amount, err
+}
+
+// Verify verifies cheque for signer, contract, beneficiary, amount, valid signature.
+func (ch *Cheque) Verify(signerKey *ecdsa.PublicKey, contract, beneficiary common.Address, sum *big.Int) (*big.Int, error) {
+ log.Trace("Verifying chequebook cheque", "cheque", ch, "sum", sum)
+ if sum == nil {
+ return nil, fmt.Errorf("invalid amount")
+ }
+
+ if ch.Beneficiary != beneficiary {
+ return nil, fmt.Errorf("beneficiary mismatch: %v != %v", ch.Beneficiary.Hex(), beneficiary.Hex())
+ }
+ if ch.Contract != contract {
+ return nil, fmt.Errorf("contract mismatch: %v != %v", ch.Contract.Hex(), contract.Hex())
+ }
+
+ amount := new(big.Int).Set(ch.Amount)
+ if sum != nil {
+ amount.Sub(amount, sum)
+ if amount.Sign() <= 0 {
+ return nil, fmt.Errorf("incorrect amount: %v <= 0", amount)
+ }
+ }
+
+ pubKey, err := crypto.SigToPub(sigHash(ch.Contract, beneficiary, ch.Amount), ch.Sig)
+ if err != nil {
+ return nil, fmt.Errorf("invalid signature: %v", err)
+ }
+ if !bytes.Equal(crypto.FromECDSAPub(pubKey), crypto.FromECDSAPub(signerKey)) {
+ return nil, fmt.Errorf("signer mismatch: %x != %x", crypto.FromECDSAPub(pubKey), crypto.FromECDSAPub(signerKey))
+ }
+ return amount, nil
+}
+
+// v/r/s representation of signature
+func sig2vrs(sig []byte) (v byte, r, s [32]byte) {
+ v = sig[64] + 27
+ copy(r[:], sig[:32])
+ copy(s[:], sig[32:64])
+ return
+}
+
+// Cash cashes the cheque by sending an Ethereum transaction.
+func (ch *Cheque) Cash(session *contract.ChequebookSession) (string, error) {
+ v, r, s := sig2vrs(ch.Sig)
+ tx, err := session.Cash(ch.Beneficiary, ch.Amount, v, r, s)
+ if err != nil {
+ return "", err
+ }
+ return tx.Hash().Hex(), nil
+}
+
+// ValidateCode checks that the on-chain code at address matches the expected chequebook
+// contract code. This is used to detect suicided chequebooks.
+func ValidateCode(ctx context.Context, b Backend, address common.Address) (bool, error) {
+ code, err := b.CodeAt(ctx, address, nil)
+ if err != nil {
+ return false, err
+ }
+ return bytes.Equal(code, common.FromHex(contract.ContractDeployedCode)), nil
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/contracts/chequebook/contract/chequebook.go b/vendor/github.com/ethereum/go-ethereum/contracts/chequebook/contract/chequebook.go
new file mode 100644
index 00000000..3129b811
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/contracts/chequebook/contract/chequebook.go
@@ -0,0 +1,367 @@
+// Code generated - DO NOT EDIT.
+// This file is a generated binding and any manual changes will be lost.
+
+package contract
+
+import (
+ "math/big"
+ "strings"
+
+ ethereum "github.com/ethereum/go-ethereum"
+ "github.com/ethereum/go-ethereum/accounts/abi"
+ "github.com/ethereum/go-ethereum/accounts/abi/bind"
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/core/types"
+ "github.com/ethereum/go-ethereum/event"
+)
+
+// ChequebookABI is the input ABI used to generate the binding from.
+const ChequebookABI = "[{\"constant\":false,\"inputs\":[],\"name\":\"kill\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"address\"}],\"name\":\"sent\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"beneficiary\",\"type\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\"},{\"name\":\"sig_v\",\"type\":\"uint8\"},{\"name\":\"sig_r\",\"type\":\"bytes32\"},{\"name\":\"sig_s\",\"type\":\"bytes32\"}],\"name\":\"cash\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"deadbeat\",\"type\":\"address\"}],\"name\":\"Overdraft\",\"type\":\"event\"}]"
+
+// ChequebookBin is the compiled bytecode used for deploying new contracts.
+const ChequebookBin = `0x606060405260008054600160a060020a033316600160a060020a03199091161790556102ec806100306000396000f3006060604052600436106100565763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166341c0e1b581146100585780637bf786f81461006b578063fbf788d61461009c575b005b341561006357600080fd5b6100566100ca565b341561007657600080fd5b61008a600160a060020a03600435166100f1565b60405190815260200160405180910390f35b34156100a757600080fd5b610056600160a060020a036004351660243560ff60443516606435608435610103565b60005433600160a060020a03908116911614156100ef57600054600160a060020a0316ff5b565b60016020526000908152604090205481565b600160a060020a0385166000908152600160205260408120548190861161012957600080fd5b3087876040516c01000000000000000000000000600160a060020a03948516810282529290931690910260148301526028820152604801604051809103902091506001828686866040516000815260200160405260006040516020015260405193845260ff90921660208085019190915260408085019290925260608401929092526080909201915160208103908084039060008661646e5a03f115156101cf57600080fd5b505060206040510351600054600160a060020a039081169116146101f257600080fd5b50600160a060020a03808716600090815260016020526040902054860390301631811161026257600160a060020a0387166000818152600160205260409081902088905582156108fc0290839051600060405180830381858888f19350505050151561025d57600080fd5b6102b7565b6000547f2250e2993c15843b32621c89447cc589ee7a9f049c026986e545d3c2c0c6f97890600160a060020a0316604051600160a060020a03909116815260200160405180910390a186600160a060020a0316ff5b505050505050505600a165627a7a72305820533e856fc37e3d64d1706bcc7dfb6b1d490c8d566ea498d9d01ec08965a896ca0029`
+
+// DeployChequebook deploys a new Ethereum contract, binding an instance of Chequebook to it.
+func DeployChequebook(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *Chequebook, error) {
+ parsed, err := abi.JSON(strings.NewReader(ChequebookABI))
+ if err != nil {
+ return common.Address{}, nil, nil, err
+ }
+ address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(ChequebookBin), backend)
+ if err != nil {
+ return common.Address{}, nil, nil, err
+ }
+ return address, tx, &Chequebook{ChequebookCaller: ChequebookCaller{contract: contract}, ChequebookTransactor: ChequebookTransactor{contract: contract}, ChequebookFilterer: ChequebookFilterer{contract: contract}}, nil
+}
+
+// Chequebook is an auto generated Go binding around an Ethereum contract.
+type Chequebook struct {
+ ChequebookCaller // Read-only binding to the contract
+ ChequebookTransactor // Write-only binding to the contract
+ ChequebookFilterer // Log filterer for contract events
+}
+
+// ChequebookCaller is an auto generated read-only Go binding around an Ethereum contract.
+type ChequebookCaller struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// ChequebookTransactor is an auto generated write-only Go binding around an Ethereum contract.
+type ChequebookTransactor struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// ChequebookFilterer is an auto generated log filtering Go binding around an Ethereum contract events.
+type ChequebookFilterer struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// ChequebookSession is an auto generated Go binding around an Ethereum contract,
+// with pre-set call and transact options.
+type ChequebookSession struct {
+ Contract *Chequebook // Generic contract binding to set the session for
+ CallOpts bind.CallOpts // Call options to use throughout this session
+ TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
+}
+
+// ChequebookCallerSession is an auto generated read-only Go binding around an Ethereum contract,
+// with pre-set call options.
+type ChequebookCallerSession struct {
+ Contract *ChequebookCaller // Generic contract caller binding to set the session for
+ CallOpts bind.CallOpts // Call options to use throughout this session
+}
+
+// ChequebookTransactorSession is an auto generated write-only Go binding around an Ethereum contract,
+// with pre-set transact options.
+type ChequebookTransactorSession struct {
+ Contract *ChequebookTransactor // Generic contract transactor binding to set the session for
+ TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
+}
+
+// ChequebookRaw is an auto generated low-level Go binding around an Ethereum contract.
+type ChequebookRaw struct {
+ Contract *Chequebook // Generic contract binding to access the raw methods on
+}
+
+// ChequebookCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract.
+type ChequebookCallerRaw struct {
+ Contract *ChequebookCaller // Generic read-only contract binding to access the raw methods on
+}
+
+// ChequebookTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract.
+type ChequebookTransactorRaw struct {
+ Contract *ChequebookTransactor // Generic write-only contract binding to access the raw methods on
+}
+
+// NewChequebook creates a new instance of Chequebook, bound to a specific deployed contract.
+func NewChequebook(address common.Address, backend bind.ContractBackend) (*Chequebook, error) {
+ contract, err := bindChequebook(address, backend, backend, backend)
+ if err != nil {
+ return nil, err
+ }
+ return &Chequebook{ChequebookCaller: ChequebookCaller{contract: contract}, ChequebookTransactor: ChequebookTransactor{contract: contract}, ChequebookFilterer: ChequebookFilterer{contract: contract}}, nil
+}
+
+// NewChequebookCaller creates a new read-only instance of Chequebook, bound to a specific deployed contract.
+func NewChequebookCaller(address common.Address, caller bind.ContractCaller) (*ChequebookCaller, error) {
+ contract, err := bindChequebook(address, caller, nil, nil)
+ if err != nil {
+ return nil, err
+ }
+ return &ChequebookCaller{contract: contract}, nil
+}
+
+// NewChequebookTransactor creates a new write-only instance of Chequebook, bound to a specific deployed contract.
+func NewChequebookTransactor(address common.Address, transactor bind.ContractTransactor) (*ChequebookTransactor, error) {
+ contract, err := bindChequebook(address, nil, transactor, nil)
+ if err != nil {
+ return nil, err
+ }
+ return &ChequebookTransactor{contract: contract}, nil
+}
+
+// NewChequebookFilterer creates a new log filterer instance of Chequebook, bound to a specific deployed contract.
+func NewChequebookFilterer(address common.Address, filterer bind.ContractFilterer) (*ChequebookFilterer, error) {
+ contract, err := bindChequebook(address, nil, nil, filterer)
+ if err != nil {
+ return nil, err
+ }
+ return &ChequebookFilterer{contract: contract}, nil
+}
+
+// bindChequebook binds a generic wrapper to an already deployed contract.
+func bindChequebook(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) {
+ parsed, err := abi.JSON(strings.NewReader(ChequebookABI))
+ if err != nil {
+ return nil, err
+ }
+ return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil
+}
+
+// Call invokes the (constant) contract method with params as input values and
+// sets the output to result. The result type might be a single field for simple
+// returns, a slice of interfaces for anonymous returns and a struct for named
+// returns.
+func (_Chequebook *ChequebookRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error {
+ return _Chequebook.Contract.ChequebookCaller.contract.Call(opts, result, method, params...)
+}
+
+// Transfer initiates a plain transaction to move funds to the contract, calling
+// its default method if one is available.
+func (_Chequebook *ChequebookRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _Chequebook.Contract.ChequebookTransactor.contract.Transfer(opts)
+}
+
+// Transact invokes the (paid) contract method with params as input values.
+func (_Chequebook *ChequebookRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+ return _Chequebook.Contract.ChequebookTransactor.contract.Transact(opts, method, params...)
+}
+
+// Call invokes the (constant) contract method with params as input values and
+// sets the output to result. The result type might be a single field for simple
+// returns, a slice of interfaces for anonymous returns and a struct for named
+// returns.
+func (_Chequebook *ChequebookCallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error {
+ return _Chequebook.Contract.contract.Call(opts, result, method, params...)
+}
+
+// Transfer initiates a plain transaction to move funds to the contract, calling
+// its default method if one is available.
+func (_Chequebook *ChequebookTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _Chequebook.Contract.contract.Transfer(opts)
+}
+
+// Transact invokes the (paid) contract method with params as input values.
+func (_Chequebook *ChequebookTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+ return _Chequebook.Contract.contract.Transact(opts, method, params...)
+}
+
+// Sent is a free data retrieval call binding the contract method 0x7bf786f8.
+//
+// Solidity: function sent( address) constant returns(uint256)
+func (_Chequebook *ChequebookCaller) Sent(opts *bind.CallOpts, arg0 common.Address) (*big.Int, error) {
+ var (
+ ret0 = new(*big.Int)
+ )
+ out := ret0
+ err := _Chequebook.contract.Call(opts, out, "sent", arg0)
+ return *ret0, err
+}
+
+// Sent is a free data retrieval call binding the contract method 0x7bf786f8.
+//
+// Solidity: function sent( address) constant returns(uint256)
+func (_Chequebook *ChequebookSession) Sent(arg0 common.Address) (*big.Int, error) {
+ return _Chequebook.Contract.Sent(&_Chequebook.CallOpts, arg0)
+}
+
+// Sent is a free data retrieval call binding the contract method 0x7bf786f8.
+//
+// Solidity: function sent( address) constant returns(uint256)
+func (_Chequebook *ChequebookCallerSession) Sent(arg0 common.Address) (*big.Int, error) {
+ return _Chequebook.Contract.Sent(&_Chequebook.CallOpts, arg0)
+}
+
+// Cash is a paid mutator transaction binding the contract method 0xfbf788d6.
+//
+// Solidity: function cash(beneficiary address, amount uint256, sig_v uint8, sig_r bytes32, sig_s bytes32) returns()
+func (_Chequebook *ChequebookTransactor) Cash(opts *bind.TransactOpts, beneficiary common.Address, amount *big.Int, sigV uint8, sigR [32]byte, sigS [32]byte) (*types.Transaction, error) {
+ return _Chequebook.contract.Transact(opts, "cash", beneficiary, amount, sigV, sigR, sigS)
+}
+
+// Cash is a paid mutator transaction binding the contract method 0xfbf788d6.
+//
+// Solidity: function cash(beneficiary address, amount uint256, sig_v uint8, sig_r bytes32, sig_s bytes32) returns()
+func (_Chequebook *ChequebookSession) Cash(beneficiary common.Address, amount *big.Int, sigV uint8, sigR [32]byte, sigS [32]byte) (*types.Transaction, error) {
+ return _Chequebook.Contract.Cash(&_Chequebook.TransactOpts, beneficiary, amount, sigV, sigR, sigS)
+}
+
+// Cash is a paid mutator transaction binding the contract method 0xfbf788d6.
+//
+// Solidity: function cash(beneficiary address, amount uint256, sig_v uint8, sig_r bytes32, sig_s bytes32) returns()
+func (_Chequebook *ChequebookTransactorSession) Cash(beneficiary common.Address, amount *big.Int, sigV uint8, sigR [32]byte, sigS [32]byte) (*types.Transaction, error) {
+ return _Chequebook.Contract.Cash(&_Chequebook.TransactOpts, beneficiary, amount, sigV, sigR, sigS)
+}
+
+// Kill is a paid mutator transaction binding the contract method 0x41c0e1b5.
+//
+// Solidity: function kill() returns()
+func (_Chequebook *ChequebookTransactor) Kill(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _Chequebook.contract.Transact(opts, "kill")
+}
+
+// Kill is a paid mutator transaction binding the contract method 0x41c0e1b5.
+//
+// Solidity: function kill() returns()
+func (_Chequebook *ChequebookSession) Kill() (*types.Transaction, error) {
+ return _Chequebook.Contract.Kill(&_Chequebook.TransactOpts)
+}
+
+// Kill is a paid mutator transaction binding the contract method 0x41c0e1b5.
+//
+// Solidity: function kill() returns()
+func (_Chequebook *ChequebookTransactorSession) Kill() (*types.Transaction, error) {
+ return _Chequebook.Contract.Kill(&_Chequebook.TransactOpts)
+}
+
+// ChequebookOverdraftIterator is returned from FilterOverdraft and is used to iterate over the raw logs and unpacked data for Overdraft events raised by the Chequebook contract.
+type ChequebookOverdraftIterator struct {
+ Event *ChequebookOverdraft // Event containing the contract specifics and raw log
+
+ contract *bind.BoundContract // Generic contract to use for unpacking event data
+ event string // Event name to use for unpacking event data
+
+ logs chan types.Log // Log channel receiving the found contract events
+ sub ethereum.Subscription // Subscription for errors, completion and termination
+ done bool // Whether the subscription completed delivering logs
+ fail error // Occurred error to stop iteration
+}
+
+// Next advances the iterator to the subsequent event, returning whether there
+// are any more events found. In case of a retrieval or parsing error, false is
+// returned and Error() can be queried for the exact failure.
+func (it *ChequebookOverdraftIterator) Next() bool {
+ // If the iterator failed, stop iterating
+ if it.fail != nil {
+ return false
+ }
+ // If the iterator completed, deliver directly whatever's available
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(ChequebookOverdraft)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+ // Iterator still in progress, wait for either a data or an error event
+ select {
+ case log := <-it.logs:
+ it.Event = new(ChequebookOverdraft)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+// Error retruned any retrieval or parsing error occurred during filtering.
+func (it *ChequebookOverdraftIterator) Error() error {
+ return it.fail
+}
+
+// Close terminates the iteration process, releasing any pending underlying
+// resources.
+func (it *ChequebookOverdraftIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+// ChequebookOverdraft represents a Overdraft event raised by the Chequebook contract.
+type ChequebookOverdraft struct {
+ Deadbeat common.Address
+ Raw types.Log // Blockchain specific contextual infos
+}
+
+// FilterOverdraft is a free log retrieval operation binding the contract event 0x2250e2993c15843b32621c89447cc589ee7a9f049c026986e545d3c2c0c6f978.
+//
+// Solidity: event Overdraft(deadbeat address)
+func (_Chequebook *ChequebookFilterer) FilterOverdraft(opts *bind.FilterOpts) (*ChequebookOverdraftIterator, error) {
+
+ logs, sub, err := _Chequebook.contract.FilterLogs(opts, "Overdraft")
+ if err != nil {
+ return nil, err
+ }
+ return &ChequebookOverdraftIterator{contract: _Chequebook.contract, event: "Overdraft", logs: logs, sub: sub}, nil
+}
+
+// WatchOverdraft is a free log subscription operation binding the contract event 0x2250e2993c15843b32621c89447cc589ee7a9f049c026986e545d3c2c0c6f978.
+//
+// Solidity: event Overdraft(deadbeat address)
+func (_Chequebook *ChequebookFilterer) WatchOverdraft(opts *bind.WatchOpts, sink chan<- *ChequebookOverdraft) (event.Subscription, error) {
+
+ logs, sub, err := _Chequebook.contract.WatchLogs(opts, "Overdraft")
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+ // New log arrived, parse the event and forward to the user
+ event := new(ChequebookOverdraft)
+ if err := _Chequebook.contract.UnpackLog(event, "Overdraft", log); err != nil {
+ return err
+ }
+ event.Raw = log
+
+ select {
+ case sink <- event:
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ }
+ }), nil
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/contracts/chequebook/contract/chequebook.sol b/vendor/github.com/ethereum/go-ethereum/contracts/chequebook/contract/chequebook.sol
new file mode 100644
index 00000000..c386ccee
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/contracts/chequebook/contract/chequebook.sol
@@ -0,0 +1,47 @@
+pragma solidity ^0.4.18;
+
+import "./mortal.sol";
+
+/// @title Chequebook for Ethereum micropayments
+/// @author Daniel A. Nagy
+contract chequebook is mortal {
+ // Cumulative paid amount in wei to each beneficiary
+ mapping (address => uint256) public sent;
+
+ /// @notice Overdraft event
+ event Overdraft(address deadbeat);
+
+ // Allow sending ether to the chequebook.
+ function() public payable { }
+
+ /// @notice Cash cheque
+ ///
+ /// @param beneficiary beneficiary address
+ /// @param amount cumulative amount in wei
+ /// @param sig_v signature parameter v
+ /// @param sig_r signature parameter r
+ /// @param sig_s signature parameter s
+ /// The digital signature is calculated on the concatenated triplet of contract address, beneficiary address and cumulative amount
+ function cash(address beneficiary, uint256 amount, uint8 sig_v, bytes32 sig_r, bytes32 sig_s) public {
+ // Check if the cheque is old.
+ // Only cheques that are more recent than the last cashed one are considered.
+ require(amount > sent[beneficiary]);
+ // Check the digital signature of the cheque.
+ bytes32 hash = keccak256(address(this), beneficiary, amount);
+ require(owner == ecrecover(hash, sig_v, sig_r, sig_s));
+ // Attempt sending the difference between the cumulative amount on the cheque
+ // and the cumulative amount on the last cashed cheque to beneficiary.
+ uint256 diff = amount - sent[beneficiary];
+ if (diff <= this.balance) {
+ // update the cumulative amount before sending
+ sent[beneficiary] = amount;
+ beneficiary.transfer(diff);
+ } else {
+ // Upon failure, punish owner for writing a bounced cheque.
+ // owner.sendToDebtorsPrison();
+ Overdraft(owner);
+ // Compensate beneficiary.
+ selfdestruct(beneficiary);
+ }
+ }
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/contracts/chequebook/contract/code.go b/vendor/github.com/ethereum/go-ethereum/contracts/chequebook/contract/code.go
new file mode 100644
index 00000000..d837a9d6
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/contracts/chequebook/contract/code.go
@@ -0,0 +1,5 @@
+package contract
+
+// ContractDeployedCode is used to detect suicides. This constant needs to be
+// updated when the contract code is changed.
+const ContractDeployedCode = "0x6060604052600436106100565763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166341c0e1b581146100585780637bf786f81461006b578063fbf788d61461009c575b005b341561006357600080fd5b6100566100ca565b341561007657600080fd5b61008a600160a060020a03600435166100f1565b60405190815260200160405180910390f35b34156100a757600080fd5b610056600160a060020a036004351660243560ff60443516606435608435610103565b60005433600160a060020a03908116911614156100ef57600054600160a060020a0316ff5b565b60016020526000908152604090205481565b600160a060020a0385166000908152600160205260408120548190861161012957600080fd5b3087876040516c01000000000000000000000000600160a060020a03948516810282529290931690910260148301526028820152604801604051809103902091506001828686866040516000815260200160405260006040516020015260405193845260ff90921660208085019190915260408085019290925260608401929092526080909201915160208103908084039060008661646e5a03f115156101cf57600080fd5b505060206040510351600054600160a060020a039081169116146101f257600080fd5b50600160a060020a03808716600090815260016020526040902054860390301631811161026257600160a060020a0387166000818152600160205260409081902088905582156108fc0290839051600060405180830381858888f19350505050151561025d57600080fd5b6102b7565b6000547f2250e2993c15843b32621c89447cc589ee7a9f049c026986e545d3c2c0c6f97890600160a060020a0316604051600160a060020a03909116815260200160405180910390a186600160a060020a0316ff5b505050505050505600a165627a7a72305820533e856fc37e3d64d1706bcc7dfb6b1d490c8d566ea498d9d01ec08965a896ca0029"
diff --git a/vendor/github.com/ethereum/go-ethereum/contracts/chequebook/contract/mortal.sol b/vendor/github.com/ethereum/go-ethereum/contracts/chequebook/contract/mortal.sol
new file mode 100644
index 00000000..c43f1e4f
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/contracts/chequebook/contract/mortal.sol
@@ -0,0 +1,10 @@
+pragma solidity ^0.4.0;
+
+import "./owned.sol";
+
+contract mortal is owned {
+ function kill() public {
+ if (msg.sender == owner)
+ selfdestruct(owner);
+ }
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/contracts/chequebook/contract/owned.sol b/vendor/github.com/ethereum/go-ethereum/contracts/chequebook/contract/owned.sol
new file mode 100644
index 00000000..ee9860d3
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/contracts/chequebook/contract/owned.sol
@@ -0,0 +1,15 @@
+pragma solidity ^0.4.0;
+
+contract owned {
+ address owner;
+
+ modifier onlyowner() {
+ if (msg.sender == owner) {
+ _;
+ }
+ }
+
+ function owned() public {
+ owner = msg.sender;
+ }
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/contracts/chequebook/gencode.go b/vendor/github.com/ethereum/go-ethereum/contracts/chequebook/gencode.go
new file mode 100644
index 00000000..ddfe8d15
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/contracts/chequebook/gencode.go
@@ -0,0 +1,70 @@
+// Copyright 2016 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+// +build none
+
+// This program generates contract/code.go, which contains the chequebook code
+// after deployment.
+package main
+
+import (
+ "fmt"
+ "io/ioutil"
+ "math/big"
+
+ "github.com/ethereum/go-ethereum/accounts/abi/bind"
+ "github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
+ "github.com/ethereum/go-ethereum/contracts/chequebook/contract"
+ "github.com/ethereum/go-ethereum/core"
+ "github.com/ethereum/go-ethereum/crypto"
+)
+
+var (
+ testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
+ testAlloc = core.GenesisAlloc{
+ crypto.PubkeyToAddress(testKey.PublicKey): {Balance: big.NewInt(500000000000)},
+ }
+)
+
+func main() {
+ backend := backends.NewSimulatedBackend(testAlloc, uint64(100000000))
+ auth := bind.NewKeyedTransactor(testKey)
+
+ // Deploy the contract, get the code.
+ addr, _, _, err := contract.DeployChequebook(auth, backend)
+ if err != nil {
+ panic(err)
+ }
+ backend.Commit()
+ code, err := backend.CodeAt(nil, addr, nil)
+ if err != nil {
+ panic(err)
+ }
+ if len(code) == 0 {
+ panic("empty code")
+ }
+
+ // Write the output file.
+ content := fmt.Sprintf(`package contract
+
+// ContractDeployedCode is used to detect suicides. This constant needs to be
+// updated when the contract code is changed.
+const ContractDeployedCode = "%#x"
+`, code)
+ if err := ioutil.WriteFile("contract/code.go", []byte(content), 0644); err != nil {
+ panic(err)
+ }
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/contracts/ens/README.md b/vendor/github.com/ethereum/go-ethereum/contracts/ens/README.md
new file mode 100644
index 00000000..f2ea1330
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/contracts/ens/README.md
@@ -0,0 +1,30 @@
+# Swarm ENS interface
+
+## Usage
+
+Full documentation for the Ethereum Name Service [can be found as EIP 137](https://github.com/ethereum/EIPs/issues/137).
+This package offers a simple binding that streamlines the registration of arbitrary UTF8 domain names to swarm content hashes.
+
+## Development
+
+The SOL file in contract subdirectory implements the ENS root registry, a simple
+first-in, first-served registrar for the root namespace, and a simple resolver contract;
+they're used in tests, and can be used to deploy these contracts for your own purposes.
+
+The solidity source code can be found at [github.com/arachnid/ens/](https://github.com/arachnid/ens/).
+
+The go bindings for ENS contracts are generated using `abigen` via the go generator:
+
+```shell
+go generate ./contracts/ens
+```
+
+## Fallback contract support
+
+In order to better support content resolution on different service providers (such as Swarm and IPFS), [EIP-1577](https://eips.ethereum.org/EIPS/eip-1577)
+was introduced and with it changes that allow applications to know _where_ content hashes are stored (i.e. if the
+requested hash resides on Swarm or IPFS).
+
+The code under `contracts/ens/contract` reflects the new Public Resolver changes and the code under `fallback_contract` allows
+us to support the old contract resolution in cases where the ENS name owner did not update her Resolver contract, until the migration
+period ends (date arbitrarily set to June 1st, 2019).
diff --git a/vendor/github.com/ethereum/go-ethereum/contracts/ens/cid.go b/vendor/github.com/ethereum/go-ethereum/contracts/ens/cid.go
new file mode 100644
index 00000000..673e8203
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/contracts/ens/cid.go
@@ -0,0 +1,121 @@
+// Copyright 2016 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+package ens
+
+import (
+ "encoding/binary"
+ "errors"
+ "fmt"
+
+ "github.com/ethereum/go-ethereum/common"
+)
+
+const (
+ cidv1 = 0x1
+
+ nsIpfs = 0xe3
+ nsSwarm = 0xe4
+
+ swarmTypecode = 0xfa // swarm manifest, see https://github.com/multiformats/multicodec/blob/master/table.csv
+ swarmHashtype = 0x1b // keccak256, see https://github.com/multiformats/multicodec/blob/master/table.csv
+
+ hashLength = 32
+)
+
+// deocodeEIP1577ContentHash decodes a chain-stored content hash from an ENS record according to EIP-1577
+// a successful decode will result the different parts of the content hash in accordance to the CID spec
+// Note: only CIDv1 is supported
+func decodeEIP1577ContentHash(buf []byte) (storageNs, contentType, hashType, hashLength uint64, hash []byte, err error) {
+ if len(buf) < 10 {
+ return 0, 0, 0, 0, nil, errors.New("buffer too short")
+ }
+
+ storageNs, n := binary.Uvarint(buf)
+
+ buf = buf[n:]
+ vers, n := binary.Uvarint(buf)
+
+ if vers != 1 {
+ return 0, 0, 0, 0, nil, fmt.Errorf("expected cid v1, got: %d", vers)
+ }
+ buf = buf[n:]
+ contentType, n = binary.Uvarint(buf)
+
+ buf = buf[n:]
+ hashType, n = binary.Uvarint(buf)
+
+ buf = buf[n:]
+ hashLength, n = binary.Uvarint(buf)
+
+ hash = buf[n:]
+
+ if len(hash) != int(hashLength) {
+ return 0, 0, 0, 0, nil, errors.New("hash length mismatch")
+ }
+ return storageNs, contentType, hashType, hashLength, hash, nil
+}
+
+func extractContentHash(buf []byte) (common.Hash, error) {
+ storageNs, _ /*contentType*/, _ /* hashType*/, decodedHashLength, hashBytes, err := decodeEIP1577ContentHash(buf)
+
+ if err != nil {
+ return common.Hash{}, err
+ }
+
+ if storageNs != nsSwarm {
+ return common.Hash{}, errors.New("unknown storage system")
+ }
+
+ //todo: for the time being we implement loose enforcement for the EIP rules until ENS manager is updated
+ /*if contentType != swarmTypecode {
+ return common.Hash{}, errors.New("unknown content type")
+ }
+
+ if hashType != swarmHashtype {
+ return common.Hash{}, errors.New("unknown multihash type")
+ }*/
+
+ if decodedHashLength != hashLength {
+ return common.Hash{}, errors.New("odd hash length, swarm expects 32 bytes")
+ }
+
+ if len(hashBytes) != int(hashLength) {
+ return common.Hash{}, errors.New("hash length mismatch")
+ }
+
+ return common.BytesToHash(buf), nil
+}
+
+func EncodeSwarmHash(hash common.Hash) ([]byte, error) {
+ var cidBytes []byte
+ var headerBytes = []byte{
+ nsSwarm, //swarm namespace
+ cidv1, // CIDv1
+ swarmTypecode, // swarm hash
+ swarmHashtype, // keccak256 hash
+ hashLength, //hash length. 32 bytes
+ }
+
+ varintbuf := make([]byte, binary.MaxVarintLen64)
+ for _, v := range headerBytes {
+ n := binary.PutUvarint(varintbuf, uint64(v))
+ cidBytes = append(cidBytes, varintbuf[:n]...)
+ }
+
+ cidBytes = append(cidBytes, hash[:]...)
+ return cidBytes, nil
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/contracts/ens/contract/ENS.sol b/vendor/github.com/ethereum/go-ethereum/contracts/ens/contract/ENS.sol
new file mode 100644
index 00000000..5ab8c92b
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/contracts/ens/contract/ENS.sol
@@ -0,0 +1,26 @@
+pragma solidity >=0.4.24;
+
+interface ENS {
+
+ // Logged when the owner of a node assigns a new owner to a subnode.
+ event NewOwner(bytes32 indexed node, bytes32 indexed label, address owner);
+
+ // Logged when the owner of a node transfers ownership to a new account.
+ event Transfer(bytes32 indexed node, address owner);
+
+ // Logged when the resolver for a node changes.
+ event NewResolver(bytes32 indexed node, address resolver);
+
+ // Logged when the TTL of a node changes
+ event NewTTL(bytes32 indexed node, uint64 ttl);
+
+
+ function setSubnodeOwner(bytes32 node, bytes32 label, address owner) external;
+ function setResolver(bytes32 node, address resolver) external;
+ function setOwner(bytes32 node, address owner) external;
+ function setTTL(bytes32 node, uint64 ttl) external;
+ function owner(bytes32 node) external view returns (address);
+ function resolver(bytes32 node) external view returns (address);
+ function ttl(bytes32 node) external view returns (uint64);
+
+}
\ No newline at end of file
diff --git a/vendor/github.com/ethereum/go-ethereum/contracts/ens/contract/ENSRegistry.sol b/vendor/github.com/ethereum/go-ethereum/contracts/ens/contract/ENSRegistry.sol
new file mode 100644
index 00000000..fa19131d
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/contracts/ens/contract/ENSRegistry.sol
@@ -0,0 +1,99 @@
+pragma solidity ^0.5.0;
+
+import "./ENS.sol";
+
+/**
+ * The ENS registry contract.
+ */
+contract ENSRegistry is ENS {
+ struct Record {
+ address owner;
+ address resolver;
+ uint64 ttl;
+ }
+
+ mapping (bytes32 => Record) records;
+
+ // Permits modifications only by the owner of the specified node.
+ modifier only_owner(bytes32 node) {
+ require(records[node].owner == msg.sender);
+ _;
+ }
+
+ /**
+ * @dev Constructs a new ENS registrar.
+ */
+ constructor() public {
+ records[0x0].owner = msg.sender;
+ }
+
+ /**
+ * @dev Transfers ownership of a node to a new address. May only be called by the current owner of the node.
+ * @param node The node to transfer ownership of.
+ * @param owner The address of the new owner.
+ */
+ function setOwner(bytes32 node, address owner) external only_owner(node) {
+ emit Transfer(node, owner);
+ records[node].owner = owner;
+ }
+
+ /**
+ * @dev Transfers ownership of a subnode keccak256(node, label) to a new address. May only be called by the owner of the parent node.
+ * @param node The parent node.
+ * @param label The hash of the label specifying the subnode.
+ * @param owner The address of the new owner.
+ */
+ function setSubnodeOwner(bytes32 node, bytes32 label, address owner) external only_owner(node) {
+ bytes32 subnode = keccak256(abi.encodePacked(node, label));
+ emit NewOwner(node, label, owner);
+ records[subnode].owner = owner;
+ }
+
+ /**
+ * @dev Sets the resolver address for the specified node.
+ * @param node The node to update.
+ * @param resolver The address of the resolver.
+ */
+ function setResolver(bytes32 node, address resolver) external only_owner(node) {
+ emit NewResolver(node, resolver);
+ records[node].resolver = resolver;
+ }
+
+ /**
+ * @dev Sets the TTL for the specified node.
+ * @param node The node to update.
+ * @param ttl The TTL in seconds.
+ */
+ function setTTL(bytes32 node, uint64 ttl) external only_owner(node) {
+ emit NewTTL(node, ttl);
+ records[node].ttl = ttl;
+ }
+
+ /**
+ * @dev Returns the address that owns the specified node.
+ * @param node The specified node.
+ * @return address of the owner.
+ */
+ function owner(bytes32 node) external view returns (address) {
+ return records[node].owner;
+ }
+
+ /**
+ * @dev Returns the address of the resolver for the specified node.
+ * @param node The specified node.
+ * @return address of the resolver.
+ */
+ function resolver(bytes32 node) external view returns (address) {
+ return records[node].resolver;
+ }
+
+ /**
+ * @dev Returns the TTL of a node, and any records associated with it.
+ * @param node The specified node.
+ * @return ttl of the node.
+ */
+ function ttl(bytes32 node) external view returns (uint64) {
+ return records[node].ttl;
+ }
+
+}
\ No newline at end of file
diff --git a/vendor/github.com/ethereum/go-ethereum/contracts/ens/contract/FIFSRegistrar.sol b/vendor/github.com/ethereum/go-ethereum/contracts/ens/contract/FIFSRegistrar.sol
new file mode 100644
index 00000000..19287408
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/contracts/ens/contract/FIFSRegistrar.sol
@@ -0,0 +1,36 @@
+pragma solidity ^0.5.0;
+
+import "./ENS.sol";
+
+/**
+ * A registrar that allocates subdomains to the first person to claim them.
+ */
+contract FIFSRegistrar {
+ ENS ens;
+ bytes32 rootNode;
+
+ modifier only_owner(bytes32 label) {
+ address currentOwner = ens.owner(keccak256(abi.encodePacked(rootNode, label)));
+ require(currentOwner == address(0x0) || currentOwner == msg.sender);
+ _;
+ }
+
+ /**
+ * Constructor.
+ * @param ensAddr The address of the ENS registry.
+ * @param node The node that this registrar administers.
+ */
+ constructor(ENS ensAddr, bytes32 node) public {
+ ens = ensAddr;
+ rootNode = node;
+ }
+
+ /**
+ * Register a name, or change the owner of an existing registration.
+ * @param label The hash of the label to register.
+ * @param owner The address of the new owner.
+ */
+ function register(bytes32 label, address owner) public only_owner(label) {
+ ens.setSubnodeOwner(rootNode, label, owner);
+ }
+}
\ No newline at end of file
diff --git a/vendor/github.com/ethereum/go-ethereum/contracts/ens/contract/PublicResolver.sol b/vendor/github.com/ethereum/go-ethereum/contracts/ens/contract/PublicResolver.sol
new file mode 100644
index 00000000..cfcd5dd6
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/contracts/ens/contract/PublicResolver.sol
@@ -0,0 +1,212 @@
+pragma solidity >=0.4.25;
+
+import "./ENS.sol";
+
+/**
+ * A simple resolver anyone can use; only allows the owner of a node to set its
+ * address.
+ */
+contract PublicResolver {
+
+ bytes4 constant INTERFACE_META_ID = 0x01ffc9a7;
+ bytes4 constant ADDR_INTERFACE_ID = 0x3b3b57de;
+ bytes4 constant NAME_INTERFACE_ID = 0x691f3431;
+ bytes4 constant ABI_INTERFACE_ID = 0x2203ab56;
+ bytes4 constant PUBKEY_INTERFACE_ID = 0xc8690233;
+ bytes4 constant TEXT_INTERFACE_ID = 0x59d1d43c;
+ bytes4 constant CONTENTHASH_INTERFACE_ID = 0xbc1c58d1;
+
+ event AddrChanged(bytes32 indexed node, address a);
+ event NameChanged(bytes32 indexed node, string name);
+ event ABIChanged(bytes32 indexed node, uint256 indexed contentType);
+ event PubkeyChanged(bytes32 indexed node, bytes32 x, bytes32 y);
+ event TextChanged(bytes32 indexed node, string indexedKey, string key);
+ event ContenthashChanged(bytes32 indexed node, bytes hash);
+
+ struct PublicKey {
+ bytes32 x;
+ bytes32 y;
+ }
+
+ struct Record {
+ address addr;
+ string name;
+ PublicKey pubkey;
+ mapping(string=>string) text;
+ mapping(uint256=>bytes) abis;
+ bytes contenthash;
+ }
+
+ ENS ens;
+
+ mapping (bytes32 => Record) records;
+
+ modifier onlyOwner(bytes32 node) {
+ require(ens.owner(node) == msg.sender);
+ _;
+ }
+
+ /**
+ * Constructor.
+ * @param ensAddr The ENS registrar contract.
+ */
+ constructor(ENS ensAddr) public {
+ ens = ensAddr;
+ }
+
+ /**
+ * Sets the address associated with an ENS node.
+ * May only be called by the owner of that node in the ENS registry.
+ * @param node The node to update.
+ * @param addr The address to set.
+ */
+ function setAddr(bytes32 node, address addr) external onlyOwner(node) {
+ records[node].addr = addr;
+ emit AddrChanged(node, addr);
+ }
+
+ /**
+ * Sets the contenthash associated with an ENS node.
+ * May only be called by the owner of that node in the ENS registry.
+ * @param node The node to update.
+ * @param hash The contenthash to set
+ */
+ function setContenthash(bytes32 node, bytes calldata hash) external onlyOwner(node) {
+ records[node].contenthash = hash;
+ emit ContenthashChanged(node, hash);
+ }
+
+ /**
+ * Sets the name associated with an ENS node, for reverse records.
+ * May only be called by the owner of that node in the ENS registry.
+ * @param node The node to update.
+ * @param name The name to set.
+ */
+ function setName(bytes32 node, string calldata name) external onlyOwner(node) {
+ records[node].name = name;
+ emit NameChanged(node, name);
+ }
+
+ /**
+ * Sets the ABI associated with an ENS node.
+ * Nodes may have one ABI of each content type. To remove an ABI, set it to
+ * the empty string.
+ * @param node The node to update.
+ * @param contentType The content type of the ABI
+ * @param data The ABI data.
+ */
+ function setABI(bytes32 node, uint256 contentType, bytes calldata data) external onlyOwner(node) {
+ // Content types must be powers of 2
+ require(((contentType - 1) & contentType) == 0);
+
+ records[node].abis[contentType] = data;
+ emit ABIChanged(node, contentType);
+ }
+
+ /**
+ * Sets the SECP256k1 public key associated with an ENS node.
+ * @param node The ENS node to query
+ * @param x the X coordinate of the curve point for the public key.
+ * @param y the Y coordinate of the curve point for the public key.
+ */
+ function setPubkey(bytes32 node, bytes32 x, bytes32 y) external onlyOwner(node) {
+ records[node].pubkey = PublicKey(x, y);
+ emit PubkeyChanged(node, x, y);
+ }
+
+ /**
+ * Sets the text data associated with an ENS node and key.
+ * May only be called by the owner of that node in the ENS registry.
+ * @param node The node to update.
+ * @param key The key to set.
+ * @param value The text data value to set.
+ */
+ function setText(bytes32 node, string calldata key, string calldata value) external onlyOwner(node) {
+ records[node].text[key] = value;
+ emit TextChanged(node, key, key);
+ }
+
+ /**
+ * Returns the text data associated with an ENS node and key.
+ * @param node The ENS node to query.
+ * @param key The text data key to query.
+ * @return The associated text data.
+ */
+ function text(bytes32 node, string calldata key) external view returns (string memory) {
+ return records[node].text[key];
+ }
+
+ /**
+ * Returns the SECP256k1 public key associated with an ENS node.
+ * Defined in EIP 619.
+ * @param node The ENS node to query
+ * @return x, y the X and Y coordinates of the curve point for the public key.
+ */
+ function pubkey(bytes32 node) external view returns (bytes32 x, bytes32 y) {
+ return (records[node].pubkey.x, records[node].pubkey.y);
+ }
+
+ /**
+ * Returns the ABI associated with an ENS node.
+ * Defined in EIP205.
+ * @param node The ENS node to query
+ * @param contentTypes A bitwise OR of the ABI formats accepted by the caller.
+ * @return contentType The content type of the return value
+ * @return data The ABI data
+ */
+ function ABI(bytes32 node, uint256 contentTypes) external view returns (uint256, bytes memory) {
+ Record storage record = records[node];
+
+ for (uint256 contentType = 1; contentType <= contentTypes; contentType <<= 1) {
+ if ((contentType & contentTypes) != 0 && record.abis[contentType].length > 0) {
+ return (contentType, record.abis[contentType]);
+ }
+ }
+
+ bytes memory empty;
+ return (0, empty);
+ }
+
+ /**
+ * Returns the name associated with an ENS node, for reverse records.
+ * Defined in EIP181.
+ * @param node The ENS node to query.
+ * @return The associated name.
+ */
+ function name(bytes32 node) external view returns (string memory) {
+ return records[node].name;
+ }
+
+ /**
+ * Returns the address associated with an ENS node.
+ * @param node The ENS node to query.
+ * @return The associated address.
+ */
+ function addr(bytes32 node) external view returns (address) {
+ return records[node].addr;
+ }
+
+ /**
+ * Returns the contenthash associated with an ENS node.
+ * @param node The ENS node to query.
+ * @return The associated contenthash.
+ */
+ function contenthash(bytes32 node) external view returns (bytes memory) {
+ return records[node].contenthash;
+ }
+
+ /**
+ * Returns true if the resolver implements the interface specified by the provided hash.
+ * @param interfaceID The ID of the interface to check for.
+ * @return True if the contract implements the requested interface.
+ */
+ function supportsInterface(bytes4 interfaceID) external pure returns (bool) {
+ return interfaceID == ADDR_INTERFACE_ID ||
+ interfaceID == NAME_INTERFACE_ID ||
+ interfaceID == ABI_INTERFACE_ID ||
+ interfaceID == PUBKEY_INTERFACE_ID ||
+ interfaceID == TEXT_INTERFACE_ID ||
+ interfaceID == CONTENTHASH_INTERFACE_ID ||
+ interfaceID == INTERFACE_META_ID;
+ }
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/contracts/ens/contract/ens.go b/vendor/github.com/ethereum/go-ethereum/contracts/ens/contract/ens.go
new file mode 100644
index 00000000..7c0aed34
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/contracts/ens/contract/ens.go
@@ -0,0 +1,892 @@
+// Code generated - DO NOT EDIT.
+// This file is a generated binding and any manual changes will be lost.
+
+package contract
+
+import (
+ "math/big"
+ "strings"
+
+ ethereum "github.com/ethereum/go-ethereum"
+ "github.com/ethereum/go-ethereum/accounts/abi"
+ "github.com/ethereum/go-ethereum/accounts/abi/bind"
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/core/types"
+ "github.com/ethereum/go-ethereum/event"
+)
+
+// Reference imports to suppress errors if they are not otherwise used.
+var (
+ _ = big.NewInt
+ _ = strings.NewReader
+ _ = ethereum.NotFound
+ _ = abi.U256
+ _ = bind.Bind
+ _ = common.Big1
+ _ = types.BloomLookup
+ _ = event.NewSubscription
+)
+
+// ENSABI is the input ABI used to generate the binding from.
+const ENSABI = "[{\"constant\":true,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"}],\"name\":\"resolver\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"}],\"name\":\"owner\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"},{\"name\":\"label\",\"type\":\"bytes32\"},{\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"setSubnodeOwner\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"},{\"name\":\"ttl\",\"type\":\"uint64\"}],\"name\":\"setTTL\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"}],\"name\":\"ttl\",\"outputs\":[{\"name\":\"\",\"type\":\"uint64\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"},{\"name\":\"resolver\",\"type\":\"address\"}],\"name\":\"setResolver\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"},{\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"setOwner\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"node\",\"type\":\"bytes32\"},{\"indexed\":true,\"name\":\"label\",\"type\":\"bytes32\"},{\"indexed\":false,\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"NewOwner\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"node\",\"type\":\"bytes32\"},{\"indexed\":false,\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"node\",\"type\":\"bytes32\"},{\"indexed\":false,\"name\":\"resolver\",\"type\":\"address\"}],\"name\":\"NewResolver\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"node\",\"type\":\"bytes32\"},{\"indexed\":false,\"name\":\"ttl\",\"type\":\"uint64\"}],\"name\":\"NewTTL\",\"type\":\"event\"}]"
+
+// ENSBin is the compiled bytecode used for deploying new contracts.
+const ENSBin = `0x`
+
+// DeployENS deploys a new Ethereum contract, binding an instance of ENS to it.
+func DeployENS(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *ENS, error) {
+ parsed, err := abi.JSON(strings.NewReader(ENSABI))
+ if err != nil {
+ return common.Address{}, nil, nil, err
+ }
+ address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(ENSBin), backend)
+ if err != nil {
+ return common.Address{}, nil, nil, err
+ }
+ return address, tx, &ENS{ENSCaller: ENSCaller{contract: contract}, ENSTransactor: ENSTransactor{contract: contract}, ENSFilterer: ENSFilterer{contract: contract}}, nil
+}
+
+// ENS is an auto generated Go binding around an Ethereum contract.
+type ENS struct {
+ ENSCaller // Read-only binding to the contract
+ ENSTransactor // Write-only binding to the contract
+ ENSFilterer // Log filterer for contract events
+}
+
+// ENSCaller is an auto generated read-only Go binding around an Ethereum contract.
+type ENSCaller struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// ENSTransactor is an auto generated write-only Go binding around an Ethereum contract.
+type ENSTransactor struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// ENSFilterer is an auto generated log filtering Go binding around an Ethereum contract events.
+type ENSFilterer struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// ENSSession is an auto generated Go binding around an Ethereum contract,
+// with pre-set call and transact options.
+type ENSSession struct {
+ Contract *ENS // Generic contract binding to set the session for
+ CallOpts bind.CallOpts // Call options to use throughout this session
+ TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
+}
+
+// ENSCallerSession is an auto generated read-only Go binding around an Ethereum contract,
+// with pre-set call options.
+type ENSCallerSession struct {
+ Contract *ENSCaller // Generic contract caller binding to set the session for
+ CallOpts bind.CallOpts // Call options to use throughout this session
+}
+
+// ENSTransactorSession is an auto generated write-only Go binding around an Ethereum contract,
+// with pre-set transact options.
+type ENSTransactorSession struct {
+ Contract *ENSTransactor // Generic contract transactor binding to set the session for
+ TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
+}
+
+// ENSRaw is an auto generated low-level Go binding around an Ethereum contract.
+type ENSRaw struct {
+ Contract *ENS // Generic contract binding to access the raw methods on
+}
+
+// ENSCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract.
+type ENSCallerRaw struct {
+ Contract *ENSCaller // Generic read-only contract binding to access the raw methods on
+}
+
+// ENSTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract.
+type ENSTransactorRaw struct {
+ Contract *ENSTransactor // Generic write-only contract binding to access the raw methods on
+}
+
+// NewENS creates a new instance of ENS, bound to a specific deployed contract.
+func NewENS(address common.Address, backend bind.ContractBackend) (*ENS, error) {
+ contract, err := bindENS(address, backend, backend, backend)
+ if err != nil {
+ return nil, err
+ }
+ return &ENS{ENSCaller: ENSCaller{contract: contract}, ENSTransactor: ENSTransactor{contract: contract}, ENSFilterer: ENSFilterer{contract: contract}}, nil
+}
+
+// NewENSCaller creates a new read-only instance of ENS, bound to a specific deployed contract.
+func NewENSCaller(address common.Address, caller bind.ContractCaller) (*ENSCaller, error) {
+ contract, err := bindENS(address, caller, nil, nil)
+ if err != nil {
+ return nil, err
+ }
+ return &ENSCaller{contract: contract}, nil
+}
+
+// NewENSTransactor creates a new write-only instance of ENS, bound to a specific deployed contract.
+func NewENSTransactor(address common.Address, transactor bind.ContractTransactor) (*ENSTransactor, error) {
+ contract, err := bindENS(address, nil, transactor, nil)
+ if err != nil {
+ return nil, err
+ }
+ return &ENSTransactor{contract: contract}, nil
+}
+
+// NewENSFilterer creates a new log filterer instance of ENS, bound to a specific deployed contract.
+func NewENSFilterer(address common.Address, filterer bind.ContractFilterer) (*ENSFilterer, error) {
+ contract, err := bindENS(address, nil, nil, filterer)
+ if err != nil {
+ return nil, err
+ }
+ return &ENSFilterer{contract: contract}, nil
+}
+
+// bindENS binds a generic wrapper to an already deployed contract.
+func bindENS(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) {
+ parsed, err := abi.JSON(strings.NewReader(ENSABI))
+ if err != nil {
+ return nil, err
+ }
+ return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil
+}
+
+// Call invokes the (constant) contract method with params as input values and
+// sets the output to result. The result type might be a single field for simple
+// returns, a slice of interfaces for anonymous returns and a struct for named
+// returns.
+func (_ENS *ENSRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error {
+ return _ENS.Contract.ENSCaller.contract.Call(opts, result, method, params...)
+}
+
+// Transfer initiates a plain transaction to move funds to the contract, calling
+// its default method if one is available.
+func (_ENS *ENSRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _ENS.Contract.ENSTransactor.contract.Transfer(opts)
+}
+
+// Transact invokes the (paid) contract method with params as input values.
+func (_ENS *ENSRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+ return _ENS.Contract.ENSTransactor.contract.Transact(opts, method, params...)
+}
+
+// Call invokes the (constant) contract method with params as input values and
+// sets the output to result. The result type might be a single field for simple
+// returns, a slice of interfaces for anonymous returns and a struct for named
+// returns.
+func (_ENS *ENSCallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error {
+ return _ENS.Contract.contract.Call(opts, result, method, params...)
+}
+
+// Transfer initiates a plain transaction to move funds to the contract, calling
+// its default method if one is available.
+func (_ENS *ENSTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _ENS.Contract.contract.Transfer(opts)
+}
+
+// Transact invokes the (paid) contract method with params as input values.
+func (_ENS *ENSTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+ return _ENS.Contract.contract.Transact(opts, method, params...)
+}
+
+// Owner is a free data retrieval call binding the contract method 0x02571be3.
+//
+// Solidity: function owner(bytes32 node) constant returns(address)
+func (_ENS *ENSCaller) Owner(opts *bind.CallOpts, node [32]byte) (common.Address, error) {
+ var (
+ ret0 = new(common.Address)
+ )
+ out := ret0
+ err := _ENS.contract.Call(opts, out, "owner", node)
+ return *ret0, err
+}
+
+// Owner is a free data retrieval call binding the contract method 0x02571be3.
+//
+// Solidity: function owner(bytes32 node) constant returns(address)
+func (_ENS *ENSSession) Owner(node [32]byte) (common.Address, error) {
+ return _ENS.Contract.Owner(&_ENS.CallOpts, node)
+}
+
+// Owner is a free data retrieval call binding the contract method 0x02571be3.
+//
+// Solidity: function owner(bytes32 node) constant returns(address)
+func (_ENS *ENSCallerSession) Owner(node [32]byte) (common.Address, error) {
+ return _ENS.Contract.Owner(&_ENS.CallOpts, node)
+}
+
+// Resolver is a free data retrieval call binding the contract method 0x0178b8bf.
+//
+// Solidity: function resolver(bytes32 node) constant returns(address)
+func (_ENS *ENSCaller) Resolver(opts *bind.CallOpts, node [32]byte) (common.Address, error) {
+ var (
+ ret0 = new(common.Address)
+ )
+ out := ret0
+ err := _ENS.contract.Call(opts, out, "resolver", node)
+ return *ret0, err
+}
+
+// Resolver is a free data retrieval call binding the contract method 0x0178b8bf.
+//
+// Solidity: function resolver(bytes32 node) constant returns(address)
+func (_ENS *ENSSession) Resolver(node [32]byte) (common.Address, error) {
+ return _ENS.Contract.Resolver(&_ENS.CallOpts, node)
+}
+
+// Resolver is a free data retrieval call binding the contract method 0x0178b8bf.
+//
+// Solidity: function resolver(bytes32 node) constant returns(address)
+func (_ENS *ENSCallerSession) Resolver(node [32]byte) (common.Address, error) {
+ return _ENS.Contract.Resolver(&_ENS.CallOpts, node)
+}
+
+// Ttl is a free data retrieval call binding the contract method 0x16a25cbd.
+//
+// Solidity: function ttl(bytes32 node) constant returns(uint64)
+func (_ENS *ENSCaller) Ttl(opts *bind.CallOpts, node [32]byte) (uint64, error) {
+ var (
+ ret0 = new(uint64)
+ )
+ out := ret0
+ err := _ENS.contract.Call(opts, out, "ttl", node)
+ return *ret0, err
+}
+
+// Ttl is a free data retrieval call binding the contract method 0x16a25cbd.
+//
+// Solidity: function ttl(bytes32 node) constant returns(uint64)
+func (_ENS *ENSSession) Ttl(node [32]byte) (uint64, error) {
+ return _ENS.Contract.Ttl(&_ENS.CallOpts, node)
+}
+
+// Ttl is a free data retrieval call binding the contract method 0x16a25cbd.
+//
+// Solidity: function ttl(bytes32 node) constant returns(uint64)
+func (_ENS *ENSCallerSession) Ttl(node [32]byte) (uint64, error) {
+ return _ENS.Contract.Ttl(&_ENS.CallOpts, node)
+}
+
+// SetOwner is a paid mutator transaction binding the contract method 0x5b0fc9c3.
+//
+// Solidity: function setOwner(bytes32 node, address owner) returns()
+func (_ENS *ENSTransactor) SetOwner(opts *bind.TransactOpts, node [32]byte, owner common.Address) (*types.Transaction, error) {
+ return _ENS.contract.Transact(opts, "setOwner", node, owner)
+}
+
+// SetOwner is a paid mutator transaction binding the contract method 0x5b0fc9c3.
+//
+// Solidity: function setOwner(bytes32 node, address owner) returns()
+func (_ENS *ENSSession) SetOwner(node [32]byte, owner common.Address) (*types.Transaction, error) {
+ return _ENS.Contract.SetOwner(&_ENS.TransactOpts, node, owner)
+}
+
+// SetOwner is a paid mutator transaction binding the contract method 0x5b0fc9c3.
+//
+// Solidity: function setOwner(bytes32 node, address owner) returns()
+func (_ENS *ENSTransactorSession) SetOwner(node [32]byte, owner common.Address) (*types.Transaction, error) {
+ return _ENS.Contract.SetOwner(&_ENS.TransactOpts, node, owner)
+}
+
+// SetResolver is a paid mutator transaction binding the contract method 0x1896f70a.
+//
+// Solidity: function setResolver(bytes32 node, address resolver) returns()
+func (_ENS *ENSTransactor) SetResolver(opts *bind.TransactOpts, node [32]byte, resolver common.Address) (*types.Transaction, error) {
+ return _ENS.contract.Transact(opts, "setResolver", node, resolver)
+}
+
+// SetResolver is a paid mutator transaction binding the contract method 0x1896f70a.
+//
+// Solidity: function setResolver(bytes32 node, address resolver) returns()
+func (_ENS *ENSSession) SetResolver(node [32]byte, resolver common.Address) (*types.Transaction, error) {
+ return _ENS.Contract.SetResolver(&_ENS.TransactOpts, node, resolver)
+}
+
+// SetResolver is a paid mutator transaction binding the contract method 0x1896f70a.
+//
+// Solidity: function setResolver(bytes32 node, address resolver) returns()
+func (_ENS *ENSTransactorSession) SetResolver(node [32]byte, resolver common.Address) (*types.Transaction, error) {
+ return _ENS.Contract.SetResolver(&_ENS.TransactOpts, node, resolver)
+}
+
+// SetSubnodeOwner is a paid mutator transaction binding the contract method 0x06ab5923.
+//
+// Solidity: function setSubnodeOwner(bytes32 node, bytes32 label, address owner) returns()
+func (_ENS *ENSTransactor) SetSubnodeOwner(opts *bind.TransactOpts, node [32]byte, label [32]byte, owner common.Address) (*types.Transaction, error) {
+ return _ENS.contract.Transact(opts, "setSubnodeOwner", node, label, owner)
+}
+
+// SetSubnodeOwner is a paid mutator transaction binding the contract method 0x06ab5923.
+//
+// Solidity: function setSubnodeOwner(bytes32 node, bytes32 label, address owner) returns()
+func (_ENS *ENSSession) SetSubnodeOwner(node [32]byte, label [32]byte, owner common.Address) (*types.Transaction, error) {
+ return _ENS.Contract.SetSubnodeOwner(&_ENS.TransactOpts, node, label, owner)
+}
+
+// SetSubnodeOwner is a paid mutator transaction binding the contract method 0x06ab5923.
+//
+// Solidity: function setSubnodeOwner(bytes32 node, bytes32 label, address owner) returns()
+func (_ENS *ENSTransactorSession) SetSubnodeOwner(node [32]byte, label [32]byte, owner common.Address) (*types.Transaction, error) {
+ return _ENS.Contract.SetSubnodeOwner(&_ENS.TransactOpts, node, label, owner)
+}
+
+// SetTTL is a paid mutator transaction binding the contract method 0x14ab9038.
+//
+// Solidity: function setTTL(bytes32 node, uint64 ttl) returns()
+func (_ENS *ENSTransactor) SetTTL(opts *bind.TransactOpts, node [32]byte, ttl uint64) (*types.Transaction, error) {
+ return _ENS.contract.Transact(opts, "setTTL", node, ttl)
+}
+
+// SetTTL is a paid mutator transaction binding the contract method 0x14ab9038.
+//
+// Solidity: function setTTL(bytes32 node, uint64 ttl) returns()
+func (_ENS *ENSSession) SetTTL(node [32]byte, ttl uint64) (*types.Transaction, error) {
+ return _ENS.Contract.SetTTL(&_ENS.TransactOpts, node, ttl)
+}
+
+// SetTTL is a paid mutator transaction binding the contract method 0x14ab9038.
+//
+// Solidity: function setTTL(bytes32 node, uint64 ttl) returns()
+func (_ENS *ENSTransactorSession) SetTTL(node [32]byte, ttl uint64) (*types.Transaction, error) {
+ return _ENS.Contract.SetTTL(&_ENS.TransactOpts, node, ttl)
+}
+
+// ENSNewOwnerIterator is returned from FilterNewOwner and is used to iterate over the raw logs and unpacked data for NewOwner events raised by the ENS contract.
+type ENSNewOwnerIterator struct {
+ Event *ENSNewOwner // Event containing the contract specifics and raw log
+
+ contract *bind.BoundContract // Generic contract to use for unpacking event data
+ event string // Event name to use for unpacking event data
+
+ logs chan types.Log // Log channel receiving the found contract events
+ sub ethereum.Subscription // Subscription for errors, completion and termination
+ done bool // Whether the subscription completed delivering logs
+ fail error // Occurred error to stop iteration
+}
+
+// Next advances the iterator to the subsequent event, returning whether there
+// are any more events found. In case of a retrieval or parsing error, false is
+// returned and Error() can be queried for the exact failure.
+func (it *ENSNewOwnerIterator) Next() bool {
+ // If the iterator failed, stop iterating
+ if it.fail != nil {
+ return false
+ }
+ // If the iterator completed, deliver directly whatever's available
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(ENSNewOwner)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+ // Iterator still in progress, wait for either a data or an error event
+ select {
+ case log := <-it.logs:
+ it.Event = new(ENSNewOwner)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+// Error returns any retrieval or parsing error occurred during filtering.
+func (it *ENSNewOwnerIterator) Error() error {
+ return it.fail
+}
+
+// Close terminates the iteration process, releasing any pending underlying
+// resources.
+func (it *ENSNewOwnerIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+// ENSNewOwner represents a NewOwner event raised by the ENS contract.
+type ENSNewOwner struct {
+ Node [32]byte
+ Label [32]byte
+ Owner common.Address
+ Raw types.Log // Blockchain specific contextual infos
+}
+
+// FilterNewOwner is a free log retrieval operation binding the contract event 0xce0457fe73731f824cc272376169235128c118b49d344817417c6d108d155e82.
+//
+// Solidity: event NewOwner(bytes32 indexed node, bytes32 indexed label, address owner)
+func (_ENS *ENSFilterer) FilterNewOwner(opts *bind.FilterOpts, node [][32]byte, label [][32]byte) (*ENSNewOwnerIterator, error) {
+
+ var nodeRule []interface{}
+ for _, nodeItem := range node {
+ nodeRule = append(nodeRule, nodeItem)
+ }
+ var labelRule []interface{}
+ for _, labelItem := range label {
+ labelRule = append(labelRule, labelItem)
+ }
+
+ logs, sub, err := _ENS.contract.FilterLogs(opts, "NewOwner", nodeRule, labelRule)
+ if err != nil {
+ return nil, err
+ }
+ return &ENSNewOwnerIterator{contract: _ENS.contract, event: "NewOwner", logs: logs, sub: sub}, nil
+}
+
+// WatchNewOwner is a free log subscription operation binding the contract event 0xce0457fe73731f824cc272376169235128c118b49d344817417c6d108d155e82.
+//
+// Solidity: event NewOwner(bytes32 indexed node, bytes32 indexed label, address owner)
+func (_ENS *ENSFilterer) WatchNewOwner(opts *bind.WatchOpts, sink chan<- *ENSNewOwner, node [][32]byte, label [][32]byte) (event.Subscription, error) {
+
+ var nodeRule []interface{}
+ for _, nodeItem := range node {
+ nodeRule = append(nodeRule, nodeItem)
+ }
+ var labelRule []interface{}
+ for _, labelItem := range label {
+ labelRule = append(labelRule, labelItem)
+ }
+
+ logs, sub, err := _ENS.contract.WatchLogs(opts, "NewOwner", nodeRule, labelRule)
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+ // New log arrived, parse the event and forward to the user
+ event := new(ENSNewOwner)
+ if err := _ENS.contract.UnpackLog(event, "NewOwner", log); err != nil {
+ return err
+ }
+ event.Raw = log
+
+ select {
+ case sink <- event:
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ }
+ }), nil
+}
+
+// ENSNewResolverIterator is returned from FilterNewResolver and is used to iterate over the raw logs and unpacked data for NewResolver events raised by the ENS contract.
+type ENSNewResolverIterator struct {
+ Event *ENSNewResolver // Event containing the contract specifics and raw log
+
+ contract *bind.BoundContract // Generic contract to use for unpacking event data
+ event string // Event name to use for unpacking event data
+
+ logs chan types.Log // Log channel receiving the found contract events
+ sub ethereum.Subscription // Subscription for errors, completion and termination
+ done bool // Whether the subscription completed delivering logs
+ fail error // Occurred error to stop iteration
+}
+
+// Next advances the iterator to the subsequent event, returning whether there
+// are any more events found. In case of a retrieval or parsing error, false is
+// returned and Error() can be queried for the exact failure.
+func (it *ENSNewResolverIterator) Next() bool {
+ // If the iterator failed, stop iterating
+ if it.fail != nil {
+ return false
+ }
+ // If the iterator completed, deliver directly whatever's available
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(ENSNewResolver)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+ // Iterator still in progress, wait for either a data or an error event
+ select {
+ case log := <-it.logs:
+ it.Event = new(ENSNewResolver)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+// Error returns any retrieval or parsing error occurred during filtering.
+func (it *ENSNewResolverIterator) Error() error {
+ return it.fail
+}
+
+// Close terminates the iteration process, releasing any pending underlying
+// resources.
+func (it *ENSNewResolverIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+// ENSNewResolver represents a NewResolver event raised by the ENS contract.
+type ENSNewResolver struct {
+ Node [32]byte
+ Resolver common.Address
+ Raw types.Log // Blockchain specific contextual infos
+}
+
+// FilterNewResolver is a free log retrieval operation binding the contract event 0x335721b01866dc23fbee8b6b2c7b1e14d6f05c28cd35a2c934239f94095602a0.
+//
+// Solidity: event NewResolver(bytes32 indexed node, address resolver)
+func (_ENS *ENSFilterer) FilterNewResolver(opts *bind.FilterOpts, node [][32]byte) (*ENSNewResolverIterator, error) {
+
+ var nodeRule []interface{}
+ for _, nodeItem := range node {
+ nodeRule = append(nodeRule, nodeItem)
+ }
+
+ logs, sub, err := _ENS.contract.FilterLogs(opts, "NewResolver", nodeRule)
+ if err != nil {
+ return nil, err
+ }
+ return &ENSNewResolverIterator{contract: _ENS.contract, event: "NewResolver", logs: logs, sub: sub}, nil
+}
+
+// WatchNewResolver is a free log subscription operation binding the contract event 0x335721b01866dc23fbee8b6b2c7b1e14d6f05c28cd35a2c934239f94095602a0.
+//
+// Solidity: event NewResolver(bytes32 indexed node, address resolver)
+func (_ENS *ENSFilterer) WatchNewResolver(opts *bind.WatchOpts, sink chan<- *ENSNewResolver, node [][32]byte) (event.Subscription, error) {
+
+ var nodeRule []interface{}
+ for _, nodeItem := range node {
+ nodeRule = append(nodeRule, nodeItem)
+ }
+
+ logs, sub, err := _ENS.contract.WatchLogs(opts, "NewResolver", nodeRule)
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+ // New log arrived, parse the event and forward to the user
+ event := new(ENSNewResolver)
+ if err := _ENS.contract.UnpackLog(event, "NewResolver", log); err != nil {
+ return err
+ }
+ event.Raw = log
+
+ select {
+ case sink <- event:
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ }
+ }), nil
+}
+
+// ENSNewTTLIterator is returned from FilterNewTTL and is used to iterate over the raw logs and unpacked data for NewTTL events raised by the ENS contract.
+type ENSNewTTLIterator struct {
+ Event *ENSNewTTL // Event containing the contract specifics and raw log
+
+ contract *bind.BoundContract // Generic contract to use for unpacking event data
+ event string // Event name to use for unpacking event data
+
+ logs chan types.Log // Log channel receiving the found contract events
+ sub ethereum.Subscription // Subscription for errors, completion and termination
+ done bool // Whether the subscription completed delivering logs
+ fail error // Occurred error to stop iteration
+}
+
+// Next advances the iterator to the subsequent event, returning whether there
+// are any more events found. In case of a retrieval or parsing error, false is
+// returned and Error() can be queried for the exact failure.
+func (it *ENSNewTTLIterator) Next() bool {
+ // If the iterator failed, stop iterating
+ if it.fail != nil {
+ return false
+ }
+ // If the iterator completed, deliver directly whatever's available
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(ENSNewTTL)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+ // Iterator still in progress, wait for either a data or an error event
+ select {
+ case log := <-it.logs:
+ it.Event = new(ENSNewTTL)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+// Error returns any retrieval or parsing error occurred during filtering.
+func (it *ENSNewTTLIterator) Error() error {
+ return it.fail
+}
+
+// Close terminates the iteration process, releasing any pending underlying
+// resources.
+func (it *ENSNewTTLIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+// ENSNewTTL represents a NewTTL event raised by the ENS contract.
+type ENSNewTTL struct {
+ Node [32]byte
+ Ttl uint64
+ Raw types.Log // Blockchain specific contextual infos
+}
+
+// FilterNewTTL is a free log retrieval operation binding the contract event 0x1d4f9bbfc9cab89d66e1a1562f2233ccbf1308cb4f63de2ead5787adddb8fa68.
+//
+// Solidity: event NewTTL(bytes32 indexed node, uint64 ttl)
+func (_ENS *ENSFilterer) FilterNewTTL(opts *bind.FilterOpts, node [][32]byte) (*ENSNewTTLIterator, error) {
+
+ var nodeRule []interface{}
+ for _, nodeItem := range node {
+ nodeRule = append(nodeRule, nodeItem)
+ }
+
+ logs, sub, err := _ENS.contract.FilterLogs(opts, "NewTTL", nodeRule)
+ if err != nil {
+ return nil, err
+ }
+ return &ENSNewTTLIterator{contract: _ENS.contract, event: "NewTTL", logs: logs, sub: sub}, nil
+}
+
+// WatchNewTTL is a free log subscription operation binding the contract event 0x1d4f9bbfc9cab89d66e1a1562f2233ccbf1308cb4f63de2ead5787adddb8fa68.
+//
+// Solidity: event NewTTL(bytes32 indexed node, uint64 ttl)
+func (_ENS *ENSFilterer) WatchNewTTL(opts *bind.WatchOpts, sink chan<- *ENSNewTTL, node [][32]byte) (event.Subscription, error) {
+
+ var nodeRule []interface{}
+ for _, nodeItem := range node {
+ nodeRule = append(nodeRule, nodeItem)
+ }
+
+ logs, sub, err := _ENS.contract.WatchLogs(opts, "NewTTL", nodeRule)
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+ // New log arrived, parse the event and forward to the user
+ event := new(ENSNewTTL)
+ if err := _ENS.contract.UnpackLog(event, "NewTTL", log); err != nil {
+ return err
+ }
+ event.Raw = log
+
+ select {
+ case sink <- event:
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ }
+ }), nil
+}
+
+// ENSTransferIterator is returned from FilterTransfer and is used to iterate over the raw logs and unpacked data for Transfer events raised by the ENS contract.
+type ENSTransferIterator struct {
+ Event *ENSTransfer // Event containing the contract specifics and raw log
+
+ contract *bind.BoundContract // Generic contract to use for unpacking event data
+ event string // Event name to use for unpacking event data
+
+ logs chan types.Log // Log channel receiving the found contract events
+ sub ethereum.Subscription // Subscription for errors, completion and termination
+ done bool // Whether the subscription completed delivering logs
+ fail error // Occurred error to stop iteration
+}
+
+// Next advances the iterator to the subsequent event, returning whether there
+// are any more events found. In case of a retrieval or parsing error, false is
+// returned and Error() can be queried for the exact failure.
+func (it *ENSTransferIterator) Next() bool {
+ // If the iterator failed, stop iterating
+ if it.fail != nil {
+ return false
+ }
+ // If the iterator completed, deliver directly whatever's available
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(ENSTransfer)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+ // Iterator still in progress, wait for either a data or an error event
+ select {
+ case log := <-it.logs:
+ it.Event = new(ENSTransfer)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+// Error returns any retrieval or parsing error occurred during filtering.
+func (it *ENSTransferIterator) Error() error {
+ return it.fail
+}
+
+// Close terminates the iteration process, releasing any pending underlying
+// resources.
+func (it *ENSTransferIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+// ENSTransfer represents a Transfer event raised by the ENS contract.
+type ENSTransfer struct {
+ Node [32]byte
+ Owner common.Address
+ Raw types.Log // Blockchain specific contextual infos
+}
+
+// FilterTransfer is a free log retrieval operation binding the contract event 0xd4735d920b0f87494915f556dd9b54c8f309026070caea5c737245152564d266.
+//
+// Solidity: event Transfer(bytes32 indexed node, address owner)
+func (_ENS *ENSFilterer) FilterTransfer(opts *bind.FilterOpts, node [][32]byte) (*ENSTransferIterator, error) {
+
+ var nodeRule []interface{}
+ for _, nodeItem := range node {
+ nodeRule = append(nodeRule, nodeItem)
+ }
+
+ logs, sub, err := _ENS.contract.FilterLogs(opts, "Transfer", nodeRule)
+ if err != nil {
+ return nil, err
+ }
+ return &ENSTransferIterator{contract: _ENS.contract, event: "Transfer", logs: logs, sub: sub}, nil
+}
+
+// WatchTransfer is a free log subscription operation binding the contract event 0xd4735d920b0f87494915f556dd9b54c8f309026070caea5c737245152564d266.
+//
+// Solidity: event Transfer(bytes32 indexed node, address owner)
+func (_ENS *ENSFilterer) WatchTransfer(opts *bind.WatchOpts, sink chan<- *ENSTransfer, node [][32]byte) (event.Subscription, error) {
+
+ var nodeRule []interface{}
+ for _, nodeItem := range node {
+ nodeRule = append(nodeRule, nodeItem)
+ }
+
+ logs, sub, err := _ENS.contract.WatchLogs(opts, "Transfer", nodeRule)
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+ // New log arrived, parse the event and forward to the user
+ event := new(ENSTransfer)
+ if err := _ENS.contract.UnpackLog(event, "Transfer", log); err != nil {
+ return err
+ }
+ event.Raw = log
+
+ select {
+ case sink <- event:
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ }
+ }), nil
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/contracts/ens/contract/ensregistry.go b/vendor/github.com/ethereum/go-ethereum/contracts/ens/contract/ensregistry.go
new file mode 100644
index 00000000..ca89a87b
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/contracts/ens/contract/ensregistry.go
@@ -0,0 +1,892 @@
+// Code generated - DO NOT EDIT.
+// This file is a generated binding and any manual changes will be lost.
+
+package contract
+
+import (
+ "math/big"
+ "strings"
+
+ ethereum "github.com/ethereum/go-ethereum"
+ "github.com/ethereum/go-ethereum/accounts/abi"
+ "github.com/ethereum/go-ethereum/accounts/abi/bind"
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/core/types"
+ "github.com/ethereum/go-ethereum/event"
+)
+
+// Reference imports to suppress errors if they are not otherwise used.
+var (
+ _ = big.NewInt
+ _ = strings.NewReader
+ _ = ethereum.NotFound
+ _ = abi.U256
+ _ = bind.Bind
+ _ = common.Big1
+ _ = types.BloomLookup
+ _ = event.NewSubscription
+)
+
+// ENSRegistryABI is the input ABI used to generate the binding from.
+const ENSRegistryABI = "[{\"constant\":true,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"}],\"name\":\"resolver\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"}],\"name\":\"owner\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"},{\"name\":\"label\",\"type\":\"bytes32\"},{\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"setSubnodeOwner\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"},{\"name\":\"ttl\",\"type\":\"uint64\"}],\"name\":\"setTTL\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"}],\"name\":\"ttl\",\"outputs\":[{\"name\":\"\",\"type\":\"uint64\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"},{\"name\":\"resolver\",\"type\":\"address\"}],\"name\":\"setResolver\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"},{\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"setOwner\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"node\",\"type\":\"bytes32\"},{\"indexed\":true,\"name\":\"label\",\"type\":\"bytes32\"},{\"indexed\":false,\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"NewOwner\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"node\",\"type\":\"bytes32\"},{\"indexed\":false,\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"node\",\"type\":\"bytes32\"},{\"indexed\":false,\"name\":\"resolver\",\"type\":\"address\"}],\"name\":\"NewResolver\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"node\",\"type\":\"bytes32\"},{\"indexed\":false,\"name\":\"ttl\",\"type\":\"uint64\"}],\"name\":\"NewTTL\",\"type\":\"event\"}]"
+
+// ENSRegistryBin is the compiled bytecode used for deploying new contracts.
+const ENSRegistryBin = `0x608060405234801561001057600080fd5b5060008080526020527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb58054600160a060020a0319163317905561059d806100596000396000f3fe6080604052600436106100825763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416630178b8bf811461008757806302571be3146100cd57806306ab5923146100f757806314ab90381461013857806316a25cbd146101725780631896f70a146101b95780635b0fc9c3146101f2575b600080fd5b34801561009357600080fd5b506100b1600480360360208110156100aa57600080fd5b503561022b565b60408051600160a060020a039092168252519081900360200190f35b3480156100d957600080fd5b506100b1600480360360208110156100f057600080fd5b5035610249565b34801561010357600080fd5b506101366004803603606081101561011a57600080fd5b5080359060208101359060400135600160a060020a0316610264565b005b34801561014457600080fd5b506101366004803603604081101561015b57600080fd5b508035906020013567ffffffffffffffff1661032e565b34801561017e57600080fd5b5061019c6004803603602081101561019557600080fd5b50356103f7565b6040805167ffffffffffffffff9092168252519081900360200190f35b3480156101c557600080fd5b50610136600480360360408110156101dc57600080fd5b5080359060200135600160a060020a031661042e565b3480156101fe57600080fd5b506101366004803603604081101561021557600080fd5b5080359060200135600160a060020a03166104d1565b600090815260208190526040902060010154600160a060020a031690565b600090815260208190526040902054600160a060020a031690565b6000838152602081905260409020548390600160a060020a0316331461028957600080fd5b6040805160208082018790528183018690528251808303840181526060830180855281519190920120600160a060020a0386169091529151859187917fce0457fe73731f824cc272376169235128c118b49d344817417c6d108d155e829181900360800190a36000908152602081905260409020805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a039390931692909217909155505050565b6000828152602081905260409020548290600160a060020a0316331461035357600080fd5b6040805167ffffffffffffffff84168152905184917f1d4f9bbfc9cab89d66e1a1562f2233ccbf1308cb4f63de2ead5787adddb8fa68919081900360200190a250600091825260208290526040909120600101805467ffffffffffffffff90921674010000000000000000000000000000000000000000027fffffffff0000000000000000ffffffffffffffffffffffffffffffffffffffff909216919091179055565b60009081526020819052604090206001015474010000000000000000000000000000000000000000900467ffffffffffffffff1690565b6000828152602081905260409020548290600160a060020a0316331461045357600080fd5b60408051600160a060020a0384168152905184917f335721b01866dc23fbee8b6b2c7b1e14d6f05c28cd35a2c934239f94095602a0919081900360200190a250600091825260208290526040909120600101805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a03909216919091179055565b6000828152602081905260409020548290600160a060020a031633146104f657600080fd5b60408051600160a060020a0384168152905184917fd4735d920b0f87494915f556dd9b54c8f309026070caea5c737245152564d266919081900360200190a250600091825260208290526040909120805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0390921691909117905556fea165627a7a723058208be97eda88107945616fbd44aa4f2f1ce188b1a930a4bc5f8e1fb7924395d1650029`
+
+// DeployENSRegistry deploys a new Ethereum contract, binding an instance of ENSRegistry to it.
+func DeployENSRegistry(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *ENSRegistry, error) {
+ parsed, err := abi.JSON(strings.NewReader(ENSRegistryABI))
+ if err != nil {
+ return common.Address{}, nil, nil, err
+ }
+ address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(ENSRegistryBin), backend)
+ if err != nil {
+ return common.Address{}, nil, nil, err
+ }
+ return address, tx, &ENSRegistry{ENSRegistryCaller: ENSRegistryCaller{contract: contract}, ENSRegistryTransactor: ENSRegistryTransactor{contract: contract}, ENSRegistryFilterer: ENSRegistryFilterer{contract: contract}}, nil
+}
+
+// ENSRegistry is an auto generated Go binding around an Ethereum contract.
+type ENSRegistry struct {
+ ENSRegistryCaller // Read-only binding to the contract
+ ENSRegistryTransactor // Write-only binding to the contract
+ ENSRegistryFilterer // Log filterer for contract events
+}
+
+// ENSRegistryCaller is an auto generated read-only Go binding around an Ethereum contract.
+type ENSRegistryCaller struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// ENSRegistryTransactor is an auto generated write-only Go binding around an Ethereum contract.
+type ENSRegistryTransactor struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// ENSRegistryFilterer is an auto generated log filtering Go binding around an Ethereum contract events.
+type ENSRegistryFilterer struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// ENSRegistrySession is an auto generated Go binding around an Ethereum contract,
+// with pre-set call and transact options.
+type ENSRegistrySession struct {
+ Contract *ENSRegistry // Generic contract binding to set the session for
+ CallOpts bind.CallOpts // Call options to use throughout this session
+ TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
+}
+
+// ENSRegistryCallerSession is an auto generated read-only Go binding around an Ethereum contract,
+// with pre-set call options.
+type ENSRegistryCallerSession struct {
+ Contract *ENSRegistryCaller // Generic contract caller binding to set the session for
+ CallOpts bind.CallOpts // Call options to use throughout this session
+}
+
+// ENSRegistryTransactorSession is an auto generated write-only Go binding around an Ethereum contract,
+// with pre-set transact options.
+type ENSRegistryTransactorSession struct {
+ Contract *ENSRegistryTransactor // Generic contract transactor binding to set the session for
+ TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
+}
+
+// ENSRegistryRaw is an auto generated low-level Go binding around an Ethereum contract.
+type ENSRegistryRaw struct {
+ Contract *ENSRegistry // Generic contract binding to access the raw methods on
+}
+
+// ENSRegistryCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract.
+type ENSRegistryCallerRaw struct {
+ Contract *ENSRegistryCaller // Generic read-only contract binding to access the raw methods on
+}
+
+// ENSRegistryTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract.
+type ENSRegistryTransactorRaw struct {
+ Contract *ENSRegistryTransactor // Generic write-only contract binding to access the raw methods on
+}
+
+// NewENSRegistry creates a new instance of ENSRegistry, bound to a specific deployed contract.
+func NewENSRegistry(address common.Address, backend bind.ContractBackend) (*ENSRegistry, error) {
+ contract, err := bindENSRegistry(address, backend, backend, backend)
+ if err != nil {
+ return nil, err
+ }
+ return &ENSRegistry{ENSRegistryCaller: ENSRegistryCaller{contract: contract}, ENSRegistryTransactor: ENSRegistryTransactor{contract: contract}, ENSRegistryFilterer: ENSRegistryFilterer{contract: contract}}, nil
+}
+
+// NewENSRegistryCaller creates a new read-only instance of ENSRegistry, bound to a specific deployed contract.
+func NewENSRegistryCaller(address common.Address, caller bind.ContractCaller) (*ENSRegistryCaller, error) {
+ contract, err := bindENSRegistry(address, caller, nil, nil)
+ if err != nil {
+ return nil, err
+ }
+ return &ENSRegistryCaller{contract: contract}, nil
+}
+
+// NewENSRegistryTransactor creates a new write-only instance of ENSRegistry, bound to a specific deployed contract.
+func NewENSRegistryTransactor(address common.Address, transactor bind.ContractTransactor) (*ENSRegistryTransactor, error) {
+ contract, err := bindENSRegistry(address, nil, transactor, nil)
+ if err != nil {
+ return nil, err
+ }
+ return &ENSRegistryTransactor{contract: contract}, nil
+}
+
+// NewENSRegistryFilterer creates a new log filterer instance of ENSRegistry, bound to a specific deployed contract.
+func NewENSRegistryFilterer(address common.Address, filterer bind.ContractFilterer) (*ENSRegistryFilterer, error) {
+ contract, err := bindENSRegistry(address, nil, nil, filterer)
+ if err != nil {
+ return nil, err
+ }
+ return &ENSRegistryFilterer{contract: contract}, nil
+}
+
+// bindENSRegistry binds a generic wrapper to an already deployed contract.
+func bindENSRegistry(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) {
+ parsed, err := abi.JSON(strings.NewReader(ENSRegistryABI))
+ if err != nil {
+ return nil, err
+ }
+ return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil
+}
+
+// Call invokes the (constant) contract method with params as input values and
+// sets the output to result. The result type might be a single field for simple
+// returns, a slice of interfaces for anonymous returns and a struct for named
+// returns.
+func (_ENSRegistry *ENSRegistryRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error {
+ return _ENSRegistry.Contract.ENSRegistryCaller.contract.Call(opts, result, method, params...)
+}
+
+// Transfer initiates a plain transaction to move funds to the contract, calling
+// its default method if one is available.
+func (_ENSRegistry *ENSRegistryRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _ENSRegistry.Contract.ENSRegistryTransactor.contract.Transfer(opts)
+}
+
+// Transact invokes the (paid) contract method with params as input values.
+func (_ENSRegistry *ENSRegistryRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+ return _ENSRegistry.Contract.ENSRegistryTransactor.contract.Transact(opts, method, params...)
+}
+
+// Call invokes the (constant) contract method with params as input values and
+// sets the output to result. The result type might be a single field for simple
+// returns, a slice of interfaces for anonymous returns and a struct for named
+// returns.
+func (_ENSRegistry *ENSRegistryCallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error {
+ return _ENSRegistry.Contract.contract.Call(opts, result, method, params...)
+}
+
+// Transfer initiates a plain transaction to move funds to the contract, calling
+// its default method if one is available.
+func (_ENSRegistry *ENSRegistryTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _ENSRegistry.Contract.contract.Transfer(opts)
+}
+
+// Transact invokes the (paid) contract method with params as input values.
+func (_ENSRegistry *ENSRegistryTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+ return _ENSRegistry.Contract.contract.Transact(opts, method, params...)
+}
+
+// Owner is a free data retrieval call binding the contract method 0x02571be3.
+//
+// Solidity: function owner(bytes32 node) constant returns(address)
+func (_ENSRegistry *ENSRegistryCaller) Owner(opts *bind.CallOpts, node [32]byte) (common.Address, error) {
+ var (
+ ret0 = new(common.Address)
+ )
+ out := ret0
+ err := _ENSRegistry.contract.Call(opts, out, "owner", node)
+ return *ret0, err
+}
+
+// Owner is a free data retrieval call binding the contract method 0x02571be3.
+//
+// Solidity: function owner(bytes32 node) constant returns(address)
+func (_ENSRegistry *ENSRegistrySession) Owner(node [32]byte) (common.Address, error) {
+ return _ENSRegistry.Contract.Owner(&_ENSRegistry.CallOpts, node)
+}
+
+// Owner is a free data retrieval call binding the contract method 0x02571be3.
+//
+// Solidity: function owner(bytes32 node) constant returns(address)
+func (_ENSRegistry *ENSRegistryCallerSession) Owner(node [32]byte) (common.Address, error) {
+ return _ENSRegistry.Contract.Owner(&_ENSRegistry.CallOpts, node)
+}
+
+// Resolver is a free data retrieval call binding the contract method 0x0178b8bf.
+//
+// Solidity: function resolver(bytes32 node) constant returns(address)
+func (_ENSRegistry *ENSRegistryCaller) Resolver(opts *bind.CallOpts, node [32]byte) (common.Address, error) {
+ var (
+ ret0 = new(common.Address)
+ )
+ out := ret0
+ err := _ENSRegistry.contract.Call(opts, out, "resolver", node)
+ return *ret0, err
+}
+
+// Resolver is a free data retrieval call binding the contract method 0x0178b8bf.
+//
+// Solidity: function resolver(bytes32 node) constant returns(address)
+func (_ENSRegistry *ENSRegistrySession) Resolver(node [32]byte) (common.Address, error) {
+ return _ENSRegistry.Contract.Resolver(&_ENSRegistry.CallOpts, node)
+}
+
+// Resolver is a free data retrieval call binding the contract method 0x0178b8bf.
+//
+// Solidity: function resolver(bytes32 node) constant returns(address)
+func (_ENSRegistry *ENSRegistryCallerSession) Resolver(node [32]byte) (common.Address, error) {
+ return _ENSRegistry.Contract.Resolver(&_ENSRegistry.CallOpts, node)
+}
+
+// Ttl is a free data retrieval call binding the contract method 0x16a25cbd.
+//
+// Solidity: function ttl(bytes32 node) constant returns(uint64)
+func (_ENSRegistry *ENSRegistryCaller) Ttl(opts *bind.CallOpts, node [32]byte) (uint64, error) {
+ var (
+ ret0 = new(uint64)
+ )
+ out := ret0
+ err := _ENSRegistry.contract.Call(opts, out, "ttl", node)
+ return *ret0, err
+}
+
+// Ttl is a free data retrieval call binding the contract method 0x16a25cbd.
+//
+// Solidity: function ttl(bytes32 node) constant returns(uint64)
+func (_ENSRegistry *ENSRegistrySession) Ttl(node [32]byte) (uint64, error) {
+ return _ENSRegistry.Contract.Ttl(&_ENSRegistry.CallOpts, node)
+}
+
+// Ttl is a free data retrieval call binding the contract method 0x16a25cbd.
+//
+// Solidity: function ttl(bytes32 node) constant returns(uint64)
+func (_ENSRegistry *ENSRegistryCallerSession) Ttl(node [32]byte) (uint64, error) {
+ return _ENSRegistry.Contract.Ttl(&_ENSRegistry.CallOpts, node)
+}
+
+// SetOwner is a paid mutator transaction binding the contract method 0x5b0fc9c3.
+//
+// Solidity: function setOwner(bytes32 node, address owner) returns()
+func (_ENSRegistry *ENSRegistryTransactor) SetOwner(opts *bind.TransactOpts, node [32]byte, owner common.Address) (*types.Transaction, error) {
+ return _ENSRegistry.contract.Transact(opts, "setOwner", node, owner)
+}
+
+// SetOwner is a paid mutator transaction binding the contract method 0x5b0fc9c3.
+//
+// Solidity: function setOwner(bytes32 node, address owner) returns()
+func (_ENSRegistry *ENSRegistrySession) SetOwner(node [32]byte, owner common.Address) (*types.Transaction, error) {
+ return _ENSRegistry.Contract.SetOwner(&_ENSRegistry.TransactOpts, node, owner)
+}
+
+// SetOwner is a paid mutator transaction binding the contract method 0x5b0fc9c3.
+//
+// Solidity: function setOwner(bytes32 node, address owner) returns()
+func (_ENSRegistry *ENSRegistryTransactorSession) SetOwner(node [32]byte, owner common.Address) (*types.Transaction, error) {
+ return _ENSRegistry.Contract.SetOwner(&_ENSRegistry.TransactOpts, node, owner)
+}
+
+// SetResolver is a paid mutator transaction binding the contract method 0x1896f70a.
+//
+// Solidity: function setResolver(bytes32 node, address resolver) returns()
+func (_ENSRegistry *ENSRegistryTransactor) SetResolver(opts *bind.TransactOpts, node [32]byte, resolver common.Address) (*types.Transaction, error) {
+ return _ENSRegistry.contract.Transact(opts, "setResolver", node, resolver)
+}
+
+// SetResolver is a paid mutator transaction binding the contract method 0x1896f70a.
+//
+// Solidity: function setResolver(bytes32 node, address resolver) returns()
+func (_ENSRegistry *ENSRegistrySession) SetResolver(node [32]byte, resolver common.Address) (*types.Transaction, error) {
+ return _ENSRegistry.Contract.SetResolver(&_ENSRegistry.TransactOpts, node, resolver)
+}
+
+// SetResolver is a paid mutator transaction binding the contract method 0x1896f70a.
+//
+// Solidity: function setResolver(bytes32 node, address resolver) returns()
+func (_ENSRegistry *ENSRegistryTransactorSession) SetResolver(node [32]byte, resolver common.Address) (*types.Transaction, error) {
+ return _ENSRegistry.Contract.SetResolver(&_ENSRegistry.TransactOpts, node, resolver)
+}
+
+// SetSubnodeOwner is a paid mutator transaction binding the contract method 0x06ab5923.
+//
+// Solidity: function setSubnodeOwner(bytes32 node, bytes32 label, address owner) returns()
+func (_ENSRegistry *ENSRegistryTransactor) SetSubnodeOwner(opts *bind.TransactOpts, node [32]byte, label [32]byte, owner common.Address) (*types.Transaction, error) {
+ return _ENSRegistry.contract.Transact(opts, "setSubnodeOwner", node, label, owner)
+}
+
+// SetSubnodeOwner is a paid mutator transaction binding the contract method 0x06ab5923.
+//
+// Solidity: function setSubnodeOwner(bytes32 node, bytes32 label, address owner) returns()
+func (_ENSRegistry *ENSRegistrySession) SetSubnodeOwner(node [32]byte, label [32]byte, owner common.Address) (*types.Transaction, error) {
+ return _ENSRegistry.Contract.SetSubnodeOwner(&_ENSRegistry.TransactOpts, node, label, owner)
+}
+
+// SetSubnodeOwner is a paid mutator transaction binding the contract method 0x06ab5923.
+//
+// Solidity: function setSubnodeOwner(bytes32 node, bytes32 label, address owner) returns()
+func (_ENSRegistry *ENSRegistryTransactorSession) SetSubnodeOwner(node [32]byte, label [32]byte, owner common.Address) (*types.Transaction, error) {
+ return _ENSRegistry.Contract.SetSubnodeOwner(&_ENSRegistry.TransactOpts, node, label, owner)
+}
+
+// SetTTL is a paid mutator transaction binding the contract method 0x14ab9038.
+//
+// Solidity: function setTTL(bytes32 node, uint64 ttl) returns()
+func (_ENSRegistry *ENSRegistryTransactor) SetTTL(opts *bind.TransactOpts, node [32]byte, ttl uint64) (*types.Transaction, error) {
+ return _ENSRegistry.contract.Transact(opts, "setTTL", node, ttl)
+}
+
+// SetTTL is a paid mutator transaction binding the contract method 0x14ab9038.
+//
+// Solidity: function setTTL(bytes32 node, uint64 ttl) returns()
+func (_ENSRegistry *ENSRegistrySession) SetTTL(node [32]byte, ttl uint64) (*types.Transaction, error) {
+ return _ENSRegistry.Contract.SetTTL(&_ENSRegistry.TransactOpts, node, ttl)
+}
+
+// SetTTL is a paid mutator transaction binding the contract method 0x14ab9038.
+//
+// Solidity: function setTTL(bytes32 node, uint64 ttl) returns()
+func (_ENSRegistry *ENSRegistryTransactorSession) SetTTL(node [32]byte, ttl uint64) (*types.Transaction, error) {
+ return _ENSRegistry.Contract.SetTTL(&_ENSRegistry.TransactOpts, node, ttl)
+}
+
+// ENSRegistryNewOwnerIterator is returned from FilterNewOwner and is used to iterate over the raw logs and unpacked data for NewOwner events raised by the ENSRegistry contract.
+type ENSRegistryNewOwnerIterator struct {
+ Event *ENSRegistryNewOwner // Event containing the contract specifics and raw log
+
+ contract *bind.BoundContract // Generic contract to use for unpacking event data
+ event string // Event name to use for unpacking event data
+
+ logs chan types.Log // Log channel receiving the found contract events
+ sub ethereum.Subscription // Subscription for errors, completion and termination
+ done bool // Whether the subscription completed delivering logs
+ fail error // Occurred error to stop iteration
+}
+
+// Next advances the iterator to the subsequent event, returning whether there
+// are any more events found. In case of a retrieval or parsing error, false is
+// returned and Error() can be queried for the exact failure.
+func (it *ENSRegistryNewOwnerIterator) Next() bool {
+ // If the iterator failed, stop iterating
+ if it.fail != nil {
+ return false
+ }
+ // If the iterator completed, deliver directly whatever's available
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(ENSRegistryNewOwner)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+ // Iterator still in progress, wait for either a data or an error event
+ select {
+ case log := <-it.logs:
+ it.Event = new(ENSRegistryNewOwner)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+// Error returns any retrieval or parsing error occurred during filtering.
+func (it *ENSRegistryNewOwnerIterator) Error() error {
+ return it.fail
+}
+
+// Close terminates the iteration process, releasing any pending underlying
+// resources.
+func (it *ENSRegistryNewOwnerIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+// ENSRegistryNewOwner represents a NewOwner event raised by the ENSRegistry contract.
+type ENSRegistryNewOwner struct {
+ Node [32]byte
+ Label [32]byte
+ Owner common.Address
+ Raw types.Log // Blockchain specific contextual infos
+}
+
+// FilterNewOwner is a free log retrieval operation binding the contract event 0xce0457fe73731f824cc272376169235128c118b49d344817417c6d108d155e82.
+//
+// Solidity: event NewOwner(bytes32 indexed node, bytes32 indexed label, address owner)
+func (_ENSRegistry *ENSRegistryFilterer) FilterNewOwner(opts *bind.FilterOpts, node [][32]byte, label [][32]byte) (*ENSRegistryNewOwnerIterator, error) {
+
+ var nodeRule []interface{}
+ for _, nodeItem := range node {
+ nodeRule = append(nodeRule, nodeItem)
+ }
+ var labelRule []interface{}
+ for _, labelItem := range label {
+ labelRule = append(labelRule, labelItem)
+ }
+
+ logs, sub, err := _ENSRegistry.contract.FilterLogs(opts, "NewOwner", nodeRule, labelRule)
+ if err != nil {
+ return nil, err
+ }
+ return &ENSRegistryNewOwnerIterator{contract: _ENSRegistry.contract, event: "NewOwner", logs: logs, sub: sub}, nil
+}
+
+// WatchNewOwner is a free log subscription operation binding the contract event 0xce0457fe73731f824cc272376169235128c118b49d344817417c6d108d155e82.
+//
+// Solidity: event NewOwner(bytes32 indexed node, bytes32 indexed label, address owner)
+func (_ENSRegistry *ENSRegistryFilterer) WatchNewOwner(opts *bind.WatchOpts, sink chan<- *ENSRegistryNewOwner, node [][32]byte, label [][32]byte) (event.Subscription, error) {
+
+ var nodeRule []interface{}
+ for _, nodeItem := range node {
+ nodeRule = append(nodeRule, nodeItem)
+ }
+ var labelRule []interface{}
+ for _, labelItem := range label {
+ labelRule = append(labelRule, labelItem)
+ }
+
+ logs, sub, err := _ENSRegistry.contract.WatchLogs(opts, "NewOwner", nodeRule, labelRule)
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+ // New log arrived, parse the event and forward to the user
+ event := new(ENSRegistryNewOwner)
+ if err := _ENSRegistry.contract.UnpackLog(event, "NewOwner", log); err != nil {
+ return err
+ }
+ event.Raw = log
+
+ select {
+ case sink <- event:
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ }
+ }), nil
+}
+
+// ENSRegistryNewResolverIterator is returned from FilterNewResolver and is used to iterate over the raw logs and unpacked data for NewResolver events raised by the ENSRegistry contract.
+type ENSRegistryNewResolverIterator struct {
+ Event *ENSRegistryNewResolver // Event containing the contract specifics and raw log
+
+ contract *bind.BoundContract // Generic contract to use for unpacking event data
+ event string // Event name to use for unpacking event data
+
+ logs chan types.Log // Log channel receiving the found contract events
+ sub ethereum.Subscription // Subscription for errors, completion and termination
+ done bool // Whether the subscription completed delivering logs
+ fail error // Occurred error to stop iteration
+}
+
+// Next advances the iterator to the subsequent event, returning whether there
+// are any more events found. In case of a retrieval or parsing error, false is
+// returned and Error() can be queried for the exact failure.
+func (it *ENSRegistryNewResolverIterator) Next() bool {
+ // If the iterator failed, stop iterating
+ if it.fail != nil {
+ return false
+ }
+ // If the iterator completed, deliver directly whatever's available
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(ENSRegistryNewResolver)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+ // Iterator still in progress, wait for either a data or an error event
+ select {
+ case log := <-it.logs:
+ it.Event = new(ENSRegistryNewResolver)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+// Error returns any retrieval or parsing error occurred during filtering.
+func (it *ENSRegistryNewResolverIterator) Error() error {
+ return it.fail
+}
+
+// Close terminates the iteration process, releasing any pending underlying
+// resources.
+func (it *ENSRegistryNewResolverIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+// ENSRegistryNewResolver represents a NewResolver event raised by the ENSRegistry contract.
+type ENSRegistryNewResolver struct {
+ Node [32]byte
+ Resolver common.Address
+ Raw types.Log // Blockchain specific contextual infos
+}
+
+// FilterNewResolver is a free log retrieval operation binding the contract event 0x335721b01866dc23fbee8b6b2c7b1e14d6f05c28cd35a2c934239f94095602a0.
+//
+// Solidity: event NewResolver(bytes32 indexed node, address resolver)
+func (_ENSRegistry *ENSRegistryFilterer) FilterNewResolver(opts *bind.FilterOpts, node [][32]byte) (*ENSRegistryNewResolverIterator, error) {
+
+ var nodeRule []interface{}
+ for _, nodeItem := range node {
+ nodeRule = append(nodeRule, nodeItem)
+ }
+
+ logs, sub, err := _ENSRegistry.contract.FilterLogs(opts, "NewResolver", nodeRule)
+ if err != nil {
+ return nil, err
+ }
+ return &ENSRegistryNewResolverIterator{contract: _ENSRegistry.contract, event: "NewResolver", logs: logs, sub: sub}, nil
+}
+
+// WatchNewResolver is a free log subscription operation binding the contract event 0x335721b01866dc23fbee8b6b2c7b1e14d6f05c28cd35a2c934239f94095602a0.
+//
+// Solidity: event NewResolver(bytes32 indexed node, address resolver)
+func (_ENSRegistry *ENSRegistryFilterer) WatchNewResolver(opts *bind.WatchOpts, sink chan<- *ENSRegistryNewResolver, node [][32]byte) (event.Subscription, error) {
+
+ var nodeRule []interface{}
+ for _, nodeItem := range node {
+ nodeRule = append(nodeRule, nodeItem)
+ }
+
+ logs, sub, err := _ENSRegistry.contract.WatchLogs(opts, "NewResolver", nodeRule)
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+ // New log arrived, parse the event and forward to the user
+ event := new(ENSRegistryNewResolver)
+ if err := _ENSRegistry.contract.UnpackLog(event, "NewResolver", log); err != nil {
+ return err
+ }
+ event.Raw = log
+
+ select {
+ case sink <- event:
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ }
+ }), nil
+}
+
+// ENSRegistryNewTTLIterator is returned from FilterNewTTL and is used to iterate over the raw logs and unpacked data for NewTTL events raised by the ENSRegistry contract.
+type ENSRegistryNewTTLIterator struct {
+ Event *ENSRegistryNewTTL // Event containing the contract specifics and raw log
+
+ contract *bind.BoundContract // Generic contract to use for unpacking event data
+ event string // Event name to use for unpacking event data
+
+ logs chan types.Log // Log channel receiving the found contract events
+ sub ethereum.Subscription // Subscription for errors, completion and termination
+ done bool // Whether the subscription completed delivering logs
+ fail error // Occurred error to stop iteration
+}
+
+// Next advances the iterator to the subsequent event, returning whether there
+// are any more events found. In case of a retrieval or parsing error, false is
+// returned and Error() can be queried for the exact failure.
+func (it *ENSRegistryNewTTLIterator) Next() bool {
+ // If the iterator failed, stop iterating
+ if it.fail != nil {
+ return false
+ }
+ // If the iterator completed, deliver directly whatever's available
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(ENSRegistryNewTTL)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+ // Iterator still in progress, wait for either a data or an error event
+ select {
+ case log := <-it.logs:
+ it.Event = new(ENSRegistryNewTTL)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+// Error returns any retrieval or parsing error occurred during filtering.
+func (it *ENSRegistryNewTTLIterator) Error() error {
+ return it.fail
+}
+
+// Close terminates the iteration process, releasing any pending underlying
+// resources.
+func (it *ENSRegistryNewTTLIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+// ENSRegistryNewTTL represents a NewTTL event raised by the ENSRegistry contract.
+type ENSRegistryNewTTL struct {
+ Node [32]byte
+ Ttl uint64
+ Raw types.Log // Blockchain specific contextual infos
+}
+
+// FilterNewTTL is a free log retrieval operation binding the contract event 0x1d4f9bbfc9cab89d66e1a1562f2233ccbf1308cb4f63de2ead5787adddb8fa68.
+//
+// Solidity: event NewTTL(bytes32 indexed node, uint64 ttl)
+func (_ENSRegistry *ENSRegistryFilterer) FilterNewTTL(opts *bind.FilterOpts, node [][32]byte) (*ENSRegistryNewTTLIterator, error) {
+
+ var nodeRule []interface{}
+ for _, nodeItem := range node {
+ nodeRule = append(nodeRule, nodeItem)
+ }
+
+ logs, sub, err := _ENSRegistry.contract.FilterLogs(opts, "NewTTL", nodeRule)
+ if err != nil {
+ return nil, err
+ }
+ return &ENSRegistryNewTTLIterator{contract: _ENSRegistry.contract, event: "NewTTL", logs: logs, sub: sub}, nil
+}
+
+// WatchNewTTL is a free log subscription operation binding the contract event 0x1d4f9bbfc9cab89d66e1a1562f2233ccbf1308cb4f63de2ead5787adddb8fa68.
+//
+// Solidity: event NewTTL(bytes32 indexed node, uint64 ttl)
+func (_ENSRegistry *ENSRegistryFilterer) WatchNewTTL(opts *bind.WatchOpts, sink chan<- *ENSRegistryNewTTL, node [][32]byte) (event.Subscription, error) {
+
+ var nodeRule []interface{}
+ for _, nodeItem := range node {
+ nodeRule = append(nodeRule, nodeItem)
+ }
+
+ logs, sub, err := _ENSRegistry.contract.WatchLogs(opts, "NewTTL", nodeRule)
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+ // New log arrived, parse the event and forward to the user
+ event := new(ENSRegistryNewTTL)
+ if err := _ENSRegistry.contract.UnpackLog(event, "NewTTL", log); err != nil {
+ return err
+ }
+ event.Raw = log
+
+ select {
+ case sink <- event:
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ }
+ }), nil
+}
+
+// ENSRegistryTransferIterator is returned from FilterTransfer and is used to iterate over the raw logs and unpacked data for Transfer events raised by the ENSRegistry contract.
+type ENSRegistryTransferIterator struct {
+ Event *ENSRegistryTransfer // Event containing the contract specifics and raw log
+
+ contract *bind.BoundContract // Generic contract to use for unpacking event data
+ event string // Event name to use for unpacking event data
+
+ logs chan types.Log // Log channel receiving the found contract events
+ sub ethereum.Subscription // Subscription for errors, completion and termination
+ done bool // Whether the subscription completed delivering logs
+ fail error // Occurred error to stop iteration
+}
+
+// Next advances the iterator to the subsequent event, returning whether there
+// are any more events found. In case of a retrieval or parsing error, false is
+// returned and Error() can be queried for the exact failure.
+func (it *ENSRegistryTransferIterator) Next() bool {
+ // If the iterator failed, stop iterating
+ if it.fail != nil {
+ return false
+ }
+ // If the iterator completed, deliver directly whatever's available
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(ENSRegistryTransfer)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+ // Iterator still in progress, wait for either a data or an error event
+ select {
+ case log := <-it.logs:
+ it.Event = new(ENSRegistryTransfer)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+// Error returns any retrieval or parsing error occurred during filtering.
+func (it *ENSRegistryTransferIterator) Error() error {
+ return it.fail
+}
+
+// Close terminates the iteration process, releasing any pending underlying
+// resources.
+func (it *ENSRegistryTransferIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+// ENSRegistryTransfer represents a Transfer event raised by the ENSRegistry contract.
+type ENSRegistryTransfer struct {
+ Node [32]byte
+ Owner common.Address
+ Raw types.Log // Blockchain specific contextual infos
+}
+
+// FilterTransfer is a free log retrieval operation binding the contract event 0xd4735d920b0f87494915f556dd9b54c8f309026070caea5c737245152564d266.
+//
+// Solidity: event Transfer(bytes32 indexed node, address owner)
+func (_ENSRegistry *ENSRegistryFilterer) FilterTransfer(opts *bind.FilterOpts, node [][32]byte) (*ENSRegistryTransferIterator, error) {
+
+ var nodeRule []interface{}
+ for _, nodeItem := range node {
+ nodeRule = append(nodeRule, nodeItem)
+ }
+
+ logs, sub, err := _ENSRegistry.contract.FilterLogs(opts, "Transfer", nodeRule)
+ if err != nil {
+ return nil, err
+ }
+ return &ENSRegistryTransferIterator{contract: _ENSRegistry.contract, event: "Transfer", logs: logs, sub: sub}, nil
+}
+
+// WatchTransfer is a free log subscription operation binding the contract event 0xd4735d920b0f87494915f556dd9b54c8f309026070caea5c737245152564d266.
+//
+// Solidity: event Transfer(bytes32 indexed node, address owner)
+func (_ENSRegistry *ENSRegistryFilterer) WatchTransfer(opts *bind.WatchOpts, sink chan<- *ENSRegistryTransfer, node [][32]byte) (event.Subscription, error) {
+
+ var nodeRule []interface{}
+ for _, nodeItem := range node {
+ nodeRule = append(nodeRule, nodeItem)
+ }
+
+ logs, sub, err := _ENSRegistry.contract.WatchLogs(opts, "Transfer", nodeRule)
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+ // New log arrived, parse the event and forward to the user
+ event := new(ENSRegistryTransfer)
+ if err := _ENSRegistry.contract.UnpackLog(event, "Transfer", log); err != nil {
+ return err
+ }
+ event.Raw = log
+
+ select {
+ case sink <- event:
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ }
+ }), nil
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/contracts/ens/contract/fifsregistrar.go b/vendor/github.com/ethereum/go-ethereum/contracts/ens/contract/fifsregistrar.go
new file mode 100644
index 00000000..97263cbe
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/contracts/ens/contract/fifsregistrar.go
@@ -0,0 +1,210 @@
+// Code generated - DO NOT EDIT.
+// This file is a generated binding and any manual changes will be lost.
+
+package contract
+
+import (
+ "math/big"
+ "strings"
+
+ ethereum "github.com/ethereum/go-ethereum"
+ "github.com/ethereum/go-ethereum/accounts/abi"
+ "github.com/ethereum/go-ethereum/accounts/abi/bind"
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/core/types"
+ "github.com/ethereum/go-ethereum/event"
+)
+
+// Reference imports to suppress errors if they are not otherwise used.
+var (
+ _ = big.NewInt
+ _ = strings.NewReader
+ _ = ethereum.NotFound
+ _ = abi.U256
+ _ = bind.Bind
+ _ = common.Big1
+ _ = types.BloomLookup
+ _ = event.NewSubscription
+)
+
+// FIFSRegistrarABI is the input ABI used to generate the binding from.
+const FIFSRegistrarABI = "[{\"constant\":false,\"inputs\":[{\"name\":\"label\",\"type\":\"bytes32\"},{\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"register\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"name\":\"ensAddr\",\"type\":\"address\"},{\"name\":\"node\",\"type\":\"bytes32\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"}]"
+
+// FIFSRegistrarBin is the compiled bytecode used for deploying new contracts.
+const FIFSRegistrarBin = `0x608060405234801561001057600080fd5b506040516040806102cc8339810180604052604081101561003057600080fd5b50805160209091015160008054600160a060020a031916600160a060020a0390931692909217825560015561026190819061006b90396000f3fe6080604052600436106100405763ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041663d22057a98114610045575b600080fd5b34801561005157600080fd5b5061008b6004803603604081101561006857600080fd5b508035906020013573ffffffffffffffffffffffffffffffffffffffff1661008d565b005b6000805460015460408051602080820193909352808201879052815180820383018152606082018084528151918501919091207f02571be3000000000000000000000000000000000000000000000000000000009091526064820152905186949373ffffffffffffffffffffffffffffffffffffffff16926302571be39260848082019391829003018186803b15801561012657600080fd5b505afa15801561013a573d6000803e3d6000fd5b505050506040513d602081101561015057600080fd5b5051905073ffffffffffffffffffffffffffffffffffffffff8116158061018c575073ffffffffffffffffffffffffffffffffffffffff811633145b151561019757600080fd5b60008054600154604080517f06ab592300000000000000000000000000000000000000000000000000000000815260048101929092526024820188905273ffffffffffffffffffffffffffffffffffffffff878116604484015290519216926306ab59239260648084019382900301818387803b15801561021757600080fd5b505af115801561022b573d6000803e3d6000fd5b505050505050505056fea165627a7a723058200f21424d48c6fc6f2bc79f5b36b3a0e3067a97d4ce084ab0e0f9106303a3ee520029`
+
+// DeployFIFSRegistrar deploys a new Ethereum contract, binding an instance of FIFSRegistrar to it.
+func DeployFIFSRegistrar(auth *bind.TransactOpts, backend bind.ContractBackend, ensAddr common.Address, node [32]byte) (common.Address, *types.Transaction, *FIFSRegistrar, error) {
+ parsed, err := abi.JSON(strings.NewReader(FIFSRegistrarABI))
+ if err != nil {
+ return common.Address{}, nil, nil, err
+ }
+ address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(FIFSRegistrarBin), backend, ensAddr, node)
+ if err != nil {
+ return common.Address{}, nil, nil, err
+ }
+ return address, tx, &FIFSRegistrar{FIFSRegistrarCaller: FIFSRegistrarCaller{contract: contract}, FIFSRegistrarTransactor: FIFSRegistrarTransactor{contract: contract}, FIFSRegistrarFilterer: FIFSRegistrarFilterer{contract: contract}}, nil
+}
+
+// FIFSRegistrar is an auto generated Go binding around an Ethereum contract.
+type FIFSRegistrar struct {
+ FIFSRegistrarCaller // Read-only binding to the contract
+ FIFSRegistrarTransactor // Write-only binding to the contract
+ FIFSRegistrarFilterer // Log filterer for contract events
+}
+
+// FIFSRegistrarCaller is an auto generated read-only Go binding around an Ethereum contract.
+type FIFSRegistrarCaller struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// FIFSRegistrarTransactor is an auto generated write-only Go binding around an Ethereum contract.
+type FIFSRegistrarTransactor struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// FIFSRegistrarFilterer is an auto generated log filtering Go binding around an Ethereum contract events.
+type FIFSRegistrarFilterer struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// FIFSRegistrarSession is an auto generated Go binding around an Ethereum contract,
+// with pre-set call and transact options.
+type FIFSRegistrarSession struct {
+ Contract *FIFSRegistrar // Generic contract binding to set the session for
+ CallOpts bind.CallOpts // Call options to use throughout this session
+ TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
+}
+
+// FIFSRegistrarCallerSession is an auto generated read-only Go binding around an Ethereum contract,
+// with pre-set call options.
+type FIFSRegistrarCallerSession struct {
+ Contract *FIFSRegistrarCaller // Generic contract caller binding to set the session for
+ CallOpts bind.CallOpts // Call options to use throughout this session
+}
+
+// FIFSRegistrarTransactorSession is an auto generated write-only Go binding around an Ethereum contract,
+// with pre-set transact options.
+type FIFSRegistrarTransactorSession struct {
+ Contract *FIFSRegistrarTransactor // Generic contract transactor binding to set the session for
+ TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
+}
+
+// FIFSRegistrarRaw is an auto generated low-level Go binding around an Ethereum contract.
+type FIFSRegistrarRaw struct {
+ Contract *FIFSRegistrar // Generic contract binding to access the raw methods on
+}
+
+// FIFSRegistrarCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract.
+type FIFSRegistrarCallerRaw struct {
+ Contract *FIFSRegistrarCaller // Generic read-only contract binding to access the raw methods on
+}
+
+// FIFSRegistrarTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract.
+type FIFSRegistrarTransactorRaw struct {
+ Contract *FIFSRegistrarTransactor // Generic write-only contract binding to access the raw methods on
+}
+
+// NewFIFSRegistrar creates a new instance of FIFSRegistrar, bound to a specific deployed contract.
+func NewFIFSRegistrar(address common.Address, backend bind.ContractBackend) (*FIFSRegistrar, error) {
+ contract, err := bindFIFSRegistrar(address, backend, backend, backend)
+ if err != nil {
+ return nil, err
+ }
+ return &FIFSRegistrar{FIFSRegistrarCaller: FIFSRegistrarCaller{contract: contract}, FIFSRegistrarTransactor: FIFSRegistrarTransactor{contract: contract}, FIFSRegistrarFilterer: FIFSRegistrarFilterer{contract: contract}}, nil
+}
+
+// NewFIFSRegistrarCaller creates a new read-only instance of FIFSRegistrar, bound to a specific deployed contract.
+func NewFIFSRegistrarCaller(address common.Address, caller bind.ContractCaller) (*FIFSRegistrarCaller, error) {
+ contract, err := bindFIFSRegistrar(address, caller, nil, nil)
+ if err != nil {
+ return nil, err
+ }
+ return &FIFSRegistrarCaller{contract: contract}, nil
+}
+
+// NewFIFSRegistrarTransactor creates a new write-only instance of FIFSRegistrar, bound to a specific deployed contract.
+func NewFIFSRegistrarTransactor(address common.Address, transactor bind.ContractTransactor) (*FIFSRegistrarTransactor, error) {
+ contract, err := bindFIFSRegistrar(address, nil, transactor, nil)
+ if err != nil {
+ return nil, err
+ }
+ return &FIFSRegistrarTransactor{contract: contract}, nil
+}
+
+// NewFIFSRegistrarFilterer creates a new log filterer instance of FIFSRegistrar, bound to a specific deployed contract.
+func NewFIFSRegistrarFilterer(address common.Address, filterer bind.ContractFilterer) (*FIFSRegistrarFilterer, error) {
+ contract, err := bindFIFSRegistrar(address, nil, nil, filterer)
+ if err != nil {
+ return nil, err
+ }
+ return &FIFSRegistrarFilterer{contract: contract}, nil
+}
+
+// bindFIFSRegistrar binds a generic wrapper to an already deployed contract.
+func bindFIFSRegistrar(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) {
+ parsed, err := abi.JSON(strings.NewReader(FIFSRegistrarABI))
+ if err != nil {
+ return nil, err
+ }
+ return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil
+}
+
+// Call invokes the (constant) contract method with params as input values and
+// sets the output to result. The result type might be a single field for simple
+// returns, a slice of interfaces for anonymous returns and a struct for named
+// returns.
+func (_FIFSRegistrar *FIFSRegistrarRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error {
+ return _FIFSRegistrar.Contract.FIFSRegistrarCaller.contract.Call(opts, result, method, params...)
+}
+
+// Transfer initiates a plain transaction to move funds to the contract, calling
+// its default method if one is available.
+func (_FIFSRegistrar *FIFSRegistrarRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _FIFSRegistrar.Contract.FIFSRegistrarTransactor.contract.Transfer(opts)
+}
+
+// Transact invokes the (paid) contract method with params as input values.
+func (_FIFSRegistrar *FIFSRegistrarRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+ return _FIFSRegistrar.Contract.FIFSRegistrarTransactor.contract.Transact(opts, method, params...)
+}
+
+// Call invokes the (constant) contract method with params as input values and
+// sets the output to result. The result type might be a single field for simple
+// returns, a slice of interfaces for anonymous returns and a struct for named
+// returns.
+func (_FIFSRegistrar *FIFSRegistrarCallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error {
+ return _FIFSRegistrar.Contract.contract.Call(opts, result, method, params...)
+}
+
+// Transfer initiates a plain transaction to move funds to the contract, calling
+// its default method if one is available.
+func (_FIFSRegistrar *FIFSRegistrarTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _FIFSRegistrar.Contract.contract.Transfer(opts)
+}
+
+// Transact invokes the (paid) contract method with params as input values.
+func (_FIFSRegistrar *FIFSRegistrarTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+ return _FIFSRegistrar.Contract.contract.Transact(opts, method, params...)
+}
+
+// Register is a paid mutator transaction binding the contract method 0xd22057a9.
+//
+// Solidity: function register(bytes32 label, address owner) returns()
+func (_FIFSRegistrar *FIFSRegistrarTransactor) Register(opts *bind.TransactOpts, label [32]byte, owner common.Address) (*types.Transaction, error) {
+ return _FIFSRegistrar.contract.Transact(opts, "register", label, owner)
+}
+
+// Register is a paid mutator transaction binding the contract method 0xd22057a9.
+//
+// Solidity: function register(bytes32 label, address owner) returns()
+func (_FIFSRegistrar *FIFSRegistrarSession) Register(label [32]byte, owner common.Address) (*types.Transaction, error) {
+ return _FIFSRegistrar.Contract.Register(&_FIFSRegistrar.TransactOpts, label, owner)
+}
+
+// Register is a paid mutator transaction binding the contract method 0xd22057a9.
+//
+// Solidity: function register(bytes32 label, address owner) returns()
+func (_FIFSRegistrar *FIFSRegistrarTransactorSession) Register(label [32]byte, owner common.Address) (*types.Transaction, error) {
+ return _FIFSRegistrar.Contract.Register(&_FIFSRegistrar.TransactOpts, label, owner)
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/contracts/ens/contract/publicresolver.go b/vendor/github.com/ethereum/go-ethereum/contracts/ens/contract/publicresolver.go
new file mode 100644
index 00000000..01bfce5e
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/contracts/ens/contract/publicresolver.go
@@ -0,0 +1,1319 @@
+// Code generated - DO NOT EDIT.
+// This file is a generated binding and any manual changes will be lost.
+
+package contract
+
+import (
+ "math/big"
+ "strings"
+
+ ethereum "github.com/ethereum/go-ethereum"
+ "github.com/ethereum/go-ethereum/accounts/abi"
+ "github.com/ethereum/go-ethereum/accounts/abi/bind"
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/core/types"
+ "github.com/ethereum/go-ethereum/event"
+)
+
+// Reference imports to suppress errors if they are not otherwise used.
+var (
+ _ = big.NewInt
+ _ = strings.NewReader
+ _ = ethereum.NotFound
+ _ = abi.U256
+ _ = bind.Bind
+ _ = common.Big1
+ _ = types.BloomLookup
+ _ = event.NewSubscription
+)
+
+// PublicResolverABI is the input ABI used to generate the binding from.
+const PublicResolverABI = "[{\"constant\":true,\"inputs\":[{\"name\":\"interfaceID\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"pure\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"},{\"name\":\"key\",\"type\":\"string\"},{\"name\":\"value\",\"type\":\"string\"}],\"name\":\"setText\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"},{\"name\":\"contentTypes\",\"type\":\"uint256\"}],\"name\":\"ABI\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"},{\"name\":\"\",\"type\":\"bytes\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"},{\"name\":\"x\",\"type\":\"bytes32\"},{\"name\":\"y\",\"type\":\"bytes32\"}],\"name\":\"setPubkey\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"},{\"name\":\"hash\",\"type\":\"bytes\"}],\"name\":\"setContenthash\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"}],\"name\":\"addr\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"},{\"name\":\"key\",\"type\":\"string\"}],\"name\":\"text\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"},{\"name\":\"contentType\",\"type\":\"uint256\"},{\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"setABI\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"}],\"name\":\"name\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"},{\"name\":\"name\",\"type\":\"string\"}],\"name\":\"setName\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"}],\"name\":\"contenthash\",\"outputs\":[{\"name\":\"\",\"type\":\"bytes\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"}],\"name\":\"pubkey\",\"outputs\":[{\"name\":\"x\",\"type\":\"bytes32\"},{\"name\":\"y\",\"type\":\"bytes32\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"},{\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"setAddr\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"name\":\"ensAddr\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"node\",\"type\":\"bytes32\"},{\"indexed\":false,\"name\":\"a\",\"type\":\"address\"}],\"name\":\"AddrChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"node\",\"type\":\"bytes32\"},{\"indexed\":false,\"name\":\"name\",\"type\":\"string\"}],\"name\":\"NameChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"node\",\"type\":\"bytes32\"},{\"indexed\":true,\"name\":\"contentType\",\"type\":\"uint256\"}],\"name\":\"ABIChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"node\",\"type\":\"bytes32\"},{\"indexed\":false,\"name\":\"x\",\"type\":\"bytes32\"},{\"indexed\":false,\"name\":\"y\",\"type\":\"bytes32\"}],\"name\":\"PubkeyChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"node\",\"type\":\"bytes32\"},{\"indexed\":false,\"name\":\"indexedKey\",\"type\":\"string\"},{\"indexed\":false,\"name\":\"key\",\"type\":\"string\"}],\"name\":\"TextChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"node\",\"type\":\"bytes32\"},{\"indexed\":false,\"name\":\"hash\",\"type\":\"bytes\"}],\"name\":\"ContenthashChanged\",\"type\":\"event\"}]"
+
+// PublicResolverBin is the compiled bytecode used for deploying new contracts.
+const PublicResolverBin = `0x608060405234801561001057600080fd5b506040516020806112ce8339810180604052602081101561003057600080fd5b505160008054600160a060020a03909216600160a060020a031990921691909117905561126c806100626000396000f3fe6080604052600436106100c45763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166301ffc9a781146100c957806310f13a8c146101115780632203ab56146101e957806329cd62ea14610298578063304e6ade146102ce5780633b3b57de1461035257806359d1d43c14610398578063623195b014610491578063691f34311461051a5780637737221314610544578063bc1c58d1146105c8578063c8690233146105f2578063d5fa2b0014610635575b600080fd5b3480156100d557600080fd5b506100fd600480360360208110156100ec57600080fd5b5035600160e060020a03191661066e565b604080519115158252519081900360200190f35b34801561011d57600080fd5b506101e76004803603606081101561013457600080fd5b8135919081019060408101602082013564010000000081111561015657600080fd5b82018360208201111561016857600080fd5b8035906020019184600183028401116401000000008311171561018a57600080fd5b9193909290916020810190356401000000008111156101a857600080fd5b8201836020820111156101ba57600080fd5b803590602001918460018302840111640100000000831117156101dc57600080fd5b5090925090506107db565b005b3480156101f557600080fd5b506102196004803603604081101561020c57600080fd5b508035906020013561094d565b6040518083815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561025c578181015183820152602001610244565b50505050905090810190601f1680156102895780820380516001836020036101000a031916815260200191505b50935050505060405180910390f35b3480156102a457600080fd5b506101e7600480360360608110156102bb57600080fd5b5080359060208101359060400135610a65565b3480156102da57600080fd5b506101e7600480360360408110156102f157600080fd5b8135919081019060408101602082013564010000000081111561031357600080fd5b82018360208201111561032557600080fd5b8035906020019184600183028401116401000000008311171561034757600080fd5b509092509050610b65565b34801561035e57600080fd5b5061037c6004803603602081101561037557600080fd5b5035610c7b565b60408051600160a060020a039092168252519081900360200190f35b3480156103a457600080fd5b5061041c600480360360408110156103bb57600080fd5b813591908101906040810160208201356401000000008111156103dd57600080fd5b8201836020820111156103ef57600080fd5b8035906020019184600183028401116401000000008311171561041157600080fd5b509092509050610c96565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561045657818101518382015260200161043e565b50505050905090810190601f1680156104835780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561049d57600080fd5b506101e7600480360360608110156104b457600080fd5b8135916020810135918101906060810160408201356401000000008111156104db57600080fd5b8201836020820111156104ed57600080fd5b8035906020019184600183028401116401000000008311171561050f57600080fd5b509092509050610d60565b34801561052657600080fd5b5061041c6004803603602081101561053d57600080fd5b5035610e5f565b34801561055057600080fd5b506101e76004803603604081101561056757600080fd5b8135919081019060408101602082013564010000000081111561058957600080fd5b82018360208201111561059b57600080fd5b803590602001918460018302840111640100000000831117156105bd57600080fd5b509092509050610f01565b3480156105d457600080fd5b5061041c600480360360208110156105eb57600080fd5b5035611018565b3480156105fe57600080fd5b5061061c6004803603602081101561061557600080fd5b5035611084565b6040805192835260208301919091528051918290030190f35b34801561064157600080fd5b506101e76004803603604081101561065857600080fd5b5080359060200135600160a060020a03166110a1565b6000600160e060020a031982167f3b3b57de0000000000000000000000000000000000000000000000000000000014806106d15750600160e060020a031982167f691f343100000000000000000000000000000000000000000000000000000000145b806107055750600160e060020a031982167f2203ab5600000000000000000000000000000000000000000000000000000000145b806107395750600160e060020a031982167fc869023300000000000000000000000000000000000000000000000000000000145b8061076d5750600160e060020a031982167f59d1d43c00000000000000000000000000000000000000000000000000000000145b806107a15750600160e060020a031982167fbc1c58d100000000000000000000000000000000000000000000000000000000145b806107d55750600160e060020a031982167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b6000546040805160e060020a6302571be302815260048101889052905187923392600160a060020a03909116916302571be391602480820192602092909190829003018186803b15801561082e57600080fd5b505afa158015610842573d6000803e3d6000fd5b505050506040513d602081101561085857600080fd5b5051600160a060020a03161461086d57600080fd5b8282600160008981526020019081526020016000206004018787604051808383808284378083019250505092505050908152602001604051809103902091906108b79291906111a5565b50857fd8c9334b1a9c2f9da342a0a2b32629c1a229b6445dad78947f674b44444a7550868688886040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a2505050505050565b600082815260016020819052604082206060915b848111610a53578085161580159061099a5750600081815260058301602052604081205460026000196101006001841615020190911604115b15610a4b57600081815260058301602090815260409182902080548351601f6002600019610100600186161502019093169290920491820184900484028101840190945280845284939192839190830182828015610a395780601f10610a0e57610100808354040283529160200191610a39565b820191906000526020600020905b815481529060010190602001808311610a1c57829003601f168201915b50505050509050935093505050610a5e565b600202610961565b506000925060609150505b9250929050565b6000546040805160e060020a6302571be302815260048101869052905185923392600160a060020a03909116916302571be391602480820192602092909190829003018186803b158015610ab857600080fd5b505afa158015610acc573d6000803e3d6000fd5b505050506040513d6020811015610ae257600080fd5b5051600160a060020a031614610af757600080fd5b604080518082018252848152602080820185815260008881526001835284902092516002840155516003909201919091558151858152908101849052815186927f1d6f5e03d3f63eb58751986629a5439baee5079ff04f345becb66e23eb154e46928290030190a250505050565b6000546040805160e060020a6302571be302815260048101869052905185923392600160a060020a03909116916302571be391602480820192602092909190829003018186803b158015610bb857600080fd5b505afa158015610bcc573d6000803e3d6000fd5b505050506040513d6020811015610be257600080fd5b5051600160a060020a031614610bf757600080fd5b6000848152600160205260409020610c139060060184846111a5565b50837fe379c1624ed7e714cc0937528a32359d69d5281337765313dba4e081b72d7578848460405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a250505050565b600090815260016020526040902054600160a060020a031690565b6060600160008581526020019081526020016000206004018383604051808383808284379190910194855250506040805160209481900385018120805460026001821615610100026000190190911604601f81018790048702830187019093528282529094909350909150830182828015610d525780601f10610d2757610100808354040283529160200191610d52565b820191906000526020600020905b815481529060010190602001808311610d3557829003601f168201915b505050505090509392505050565b6000546040805160e060020a6302571be302815260048101879052905186923392600160a060020a03909116916302571be391602480820192602092909190829003018186803b158015610db357600080fd5b505afa158015610dc7573d6000803e3d6000fd5b505050506040513d6020811015610ddd57600080fd5b5051600160a060020a031614610df257600080fd5b6000198401841615610e0357600080fd5b60008581526001602090815260408083208784526005019091529020610e2a9084846111a5565b50604051849086907faa121bbeef5f32f5961a2a28966e769023910fc9479059ee3495d4c1a696efe390600090a35050505050565b600081815260016020818152604092839020820180548451600294821615610100026000190190911693909304601f81018390048302840183019094528383526060939091830182828015610ef55780601f10610eca57610100808354040283529160200191610ef5565b820191906000526020600020905b815481529060010190602001808311610ed857829003601f168201915b50505050509050919050565b6000546040805160e060020a6302571be302815260048101869052905185923392600160a060020a03909116916302571be391602480820192602092909190829003018186803b158015610f5457600080fd5b505afa158015610f68573d6000803e3d6000fd5b505050506040513d6020811015610f7e57600080fd5b5051600160a060020a031614610f9357600080fd5b6000848152600160208190526040909120610fb0910184846111a5565b50837fb7d29e911041e8d9b843369e890bcb72c9388692ba48b65ac54e7214c4c348f7848460405180806020018281038252848482818152602001925080828437600083820152604051601f909101601f19169092018290039550909350505050a250505050565b60008181526001602081815260409283902060060180548451600294821615610100026000190190911693909304601f81018390048302840183019094528383526060939091830182828015610ef55780601f10610eca57610100808354040283529160200191610ef5565b600090815260016020526040902060028101546003909101549091565b6000546040805160e060020a6302571be302815260048101859052905184923392600160a060020a03909116916302571be391602480820192602092909190829003018186803b1580156110f457600080fd5b505afa158015611108573d6000803e3d6000fd5b505050506040513d602081101561111e57600080fd5b5051600160a060020a03161461113357600080fd5b600083815260016020908152604091829020805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0386169081179091558251908152915185927f52d7d861f09ab3d26239d492e8968629f95e9e318cf0b73bfddc441522a15fd292908290030190a2505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106111e65782800160ff19823516178555611213565b82800160010185558215611213579182015b828111156112135782358255916020019190600101906111f8565b5061121f929150611223565b5090565b61123d91905b8082111561121f5760008155600101611229565b9056fea165627a7a7230582047f310fc746ab2e282cf63ba794d20abb361f9284c6c5f2a2e26151e5b7fab600029`
+
+// DeployPublicResolver deploys a new Ethereum contract, binding an instance of PublicResolver to it.
+func DeployPublicResolver(auth *bind.TransactOpts, backend bind.ContractBackend, ensAddr common.Address) (common.Address, *types.Transaction, *PublicResolver, error) {
+ parsed, err := abi.JSON(strings.NewReader(PublicResolverABI))
+ if err != nil {
+ return common.Address{}, nil, nil, err
+ }
+ address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(PublicResolverBin), backend, ensAddr)
+ if err != nil {
+ return common.Address{}, nil, nil, err
+ }
+ return address, tx, &PublicResolver{PublicResolverCaller: PublicResolverCaller{contract: contract}, PublicResolverTransactor: PublicResolverTransactor{contract: contract}, PublicResolverFilterer: PublicResolverFilterer{contract: contract}}, nil
+}
+
+// PublicResolver is an auto generated Go binding around an Ethereum contract.
+type PublicResolver struct {
+ PublicResolverCaller // Read-only binding to the contract
+ PublicResolverTransactor // Write-only binding to the contract
+ PublicResolverFilterer // Log filterer for contract events
+}
+
+// PublicResolverCaller is an auto generated read-only Go binding around an Ethereum contract.
+type PublicResolverCaller struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// PublicResolverTransactor is an auto generated write-only Go binding around an Ethereum contract.
+type PublicResolverTransactor struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// PublicResolverFilterer is an auto generated log filtering Go binding around an Ethereum contract events.
+type PublicResolverFilterer struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// PublicResolverSession is an auto generated Go binding around an Ethereum contract,
+// with pre-set call and transact options.
+type PublicResolverSession struct {
+ Contract *PublicResolver // Generic contract binding to set the session for
+ CallOpts bind.CallOpts // Call options to use throughout this session
+ TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
+}
+
+// PublicResolverCallerSession is an auto generated read-only Go binding around an Ethereum contract,
+// with pre-set call options.
+type PublicResolverCallerSession struct {
+ Contract *PublicResolverCaller // Generic contract caller binding to set the session for
+ CallOpts bind.CallOpts // Call options to use throughout this session
+}
+
+// PublicResolverTransactorSession is an auto generated write-only Go binding around an Ethereum contract,
+// with pre-set transact options.
+type PublicResolverTransactorSession struct {
+ Contract *PublicResolverTransactor // Generic contract transactor binding to set the session for
+ TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
+}
+
+// PublicResolverRaw is an auto generated low-level Go binding around an Ethereum contract.
+type PublicResolverRaw struct {
+ Contract *PublicResolver // Generic contract binding to access the raw methods on
+}
+
+// PublicResolverCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract.
+type PublicResolverCallerRaw struct {
+ Contract *PublicResolverCaller // Generic read-only contract binding to access the raw methods on
+}
+
+// PublicResolverTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract.
+type PublicResolverTransactorRaw struct {
+ Contract *PublicResolverTransactor // Generic write-only contract binding to access the raw methods on
+}
+
+// NewPublicResolver creates a new instance of PublicResolver, bound to a specific deployed contract.
+func NewPublicResolver(address common.Address, backend bind.ContractBackend) (*PublicResolver, error) {
+ contract, err := bindPublicResolver(address, backend, backend, backend)
+ if err != nil {
+ return nil, err
+ }
+ return &PublicResolver{PublicResolverCaller: PublicResolverCaller{contract: contract}, PublicResolverTransactor: PublicResolverTransactor{contract: contract}, PublicResolverFilterer: PublicResolverFilterer{contract: contract}}, nil
+}
+
+// NewPublicResolverCaller creates a new read-only instance of PublicResolver, bound to a specific deployed contract.
+func NewPublicResolverCaller(address common.Address, caller bind.ContractCaller) (*PublicResolverCaller, error) {
+ contract, err := bindPublicResolver(address, caller, nil, nil)
+ if err != nil {
+ return nil, err
+ }
+ return &PublicResolverCaller{contract: contract}, nil
+}
+
+// NewPublicResolverTransactor creates a new write-only instance of PublicResolver, bound to a specific deployed contract.
+func NewPublicResolverTransactor(address common.Address, transactor bind.ContractTransactor) (*PublicResolverTransactor, error) {
+ contract, err := bindPublicResolver(address, nil, transactor, nil)
+ if err != nil {
+ return nil, err
+ }
+ return &PublicResolverTransactor{contract: contract}, nil
+}
+
+// NewPublicResolverFilterer creates a new log filterer instance of PublicResolver, bound to a specific deployed contract.
+func NewPublicResolverFilterer(address common.Address, filterer bind.ContractFilterer) (*PublicResolverFilterer, error) {
+ contract, err := bindPublicResolver(address, nil, nil, filterer)
+ if err != nil {
+ return nil, err
+ }
+ return &PublicResolverFilterer{contract: contract}, nil
+}
+
+// bindPublicResolver binds a generic wrapper to an already deployed contract.
+func bindPublicResolver(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) {
+ parsed, err := abi.JSON(strings.NewReader(PublicResolverABI))
+ if err != nil {
+ return nil, err
+ }
+ return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil
+}
+
+// Call invokes the (constant) contract method with params as input values and
+// sets the output to result. The result type might be a single field for simple
+// returns, a slice of interfaces for anonymous returns and a struct for named
+// returns.
+func (_PublicResolver *PublicResolverRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error {
+ return _PublicResolver.Contract.PublicResolverCaller.contract.Call(opts, result, method, params...)
+}
+
+// Transfer initiates a plain transaction to move funds to the contract, calling
+// its default method if one is available.
+func (_PublicResolver *PublicResolverRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _PublicResolver.Contract.PublicResolverTransactor.contract.Transfer(opts)
+}
+
+// Transact invokes the (paid) contract method with params as input values.
+func (_PublicResolver *PublicResolverRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+ return _PublicResolver.Contract.PublicResolverTransactor.contract.Transact(opts, method, params...)
+}
+
+// Call invokes the (constant) contract method with params as input values and
+// sets the output to result. The result type might be a single field for simple
+// returns, a slice of interfaces for anonymous returns and a struct for named
+// returns.
+func (_PublicResolver *PublicResolverCallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error {
+ return _PublicResolver.Contract.contract.Call(opts, result, method, params...)
+}
+
+// Transfer initiates a plain transaction to move funds to the contract, calling
+// its default method if one is available.
+func (_PublicResolver *PublicResolverTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _PublicResolver.Contract.contract.Transfer(opts)
+}
+
+// Transact invokes the (paid) contract method with params as input values.
+func (_PublicResolver *PublicResolverTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+ return _PublicResolver.Contract.contract.Transact(opts, method, params...)
+}
+
+// ABI is a free data retrieval call binding the contract method 0x2203ab56.
+//
+// Solidity: function ABI(bytes32 node, uint256 contentTypes) constant returns(uint256, bytes)
+func (_PublicResolver *PublicResolverCaller) ABI(opts *bind.CallOpts, node [32]byte, contentTypes *big.Int) (*big.Int, []byte, error) {
+ var (
+ ret0 = new(*big.Int)
+ ret1 = new([]byte)
+ )
+ out := &[]interface{}{
+ ret0,
+ ret1,
+ }
+ err := _PublicResolver.contract.Call(opts, out, "ABI", node, contentTypes)
+ return *ret0, *ret1, err
+}
+
+// ABI is a free data retrieval call binding the contract method 0x2203ab56.
+//
+// Solidity: function ABI(bytes32 node, uint256 contentTypes) constant returns(uint256, bytes)
+func (_PublicResolver *PublicResolverSession) ABI(node [32]byte, contentTypes *big.Int) (*big.Int, []byte, error) {
+ return _PublicResolver.Contract.ABI(&_PublicResolver.CallOpts, node, contentTypes)
+}
+
+// ABI is a free data retrieval call binding the contract method 0x2203ab56.
+//
+// Solidity: function ABI(bytes32 node, uint256 contentTypes) constant returns(uint256, bytes)
+func (_PublicResolver *PublicResolverCallerSession) ABI(node [32]byte, contentTypes *big.Int) (*big.Int, []byte, error) {
+ return _PublicResolver.Contract.ABI(&_PublicResolver.CallOpts, node, contentTypes)
+}
+
+// Addr is a free data retrieval call binding the contract method 0x3b3b57de.
+//
+// Solidity: function addr(bytes32 node) constant returns(address)
+func (_PublicResolver *PublicResolverCaller) Addr(opts *bind.CallOpts, node [32]byte) (common.Address, error) {
+ var (
+ ret0 = new(common.Address)
+ )
+ out := ret0
+ err := _PublicResolver.contract.Call(opts, out, "addr", node)
+ return *ret0, err
+}
+
+// Addr is a free data retrieval call binding the contract method 0x3b3b57de.
+//
+// Solidity: function addr(bytes32 node) constant returns(address)
+func (_PublicResolver *PublicResolverSession) Addr(node [32]byte) (common.Address, error) {
+ return _PublicResolver.Contract.Addr(&_PublicResolver.CallOpts, node)
+}
+
+// Addr is a free data retrieval call binding the contract method 0x3b3b57de.
+//
+// Solidity: function addr(bytes32 node) constant returns(address)
+func (_PublicResolver *PublicResolverCallerSession) Addr(node [32]byte) (common.Address, error) {
+ return _PublicResolver.Contract.Addr(&_PublicResolver.CallOpts, node)
+}
+
+// Contenthash is a free data retrieval call binding the contract method 0xbc1c58d1.
+//
+// Solidity: function contenthash(bytes32 node) constant returns(bytes)
+func (_PublicResolver *PublicResolverCaller) Contenthash(opts *bind.CallOpts, node [32]byte) ([]byte, error) {
+ var (
+ ret0 = new([]byte)
+ )
+ out := ret0
+ err := _PublicResolver.contract.Call(opts, out, "contenthash", node)
+ return *ret0, err
+}
+
+// Contenthash is a free data retrieval call binding the contract method 0xbc1c58d1.
+//
+// Solidity: function contenthash(bytes32 node) constant returns(bytes)
+func (_PublicResolver *PublicResolverSession) Contenthash(node [32]byte) ([]byte, error) {
+ return _PublicResolver.Contract.Contenthash(&_PublicResolver.CallOpts, node)
+}
+
+// Contenthash is a free data retrieval call binding the contract method 0xbc1c58d1.
+//
+// Solidity: function contenthash(bytes32 node) constant returns(bytes)
+func (_PublicResolver *PublicResolverCallerSession) Contenthash(node [32]byte) ([]byte, error) {
+ return _PublicResolver.Contract.Contenthash(&_PublicResolver.CallOpts, node)
+}
+
+// Name is a free data retrieval call binding the contract method 0x691f3431.
+//
+// Solidity: function name(bytes32 node) constant returns(string)
+func (_PublicResolver *PublicResolverCaller) Name(opts *bind.CallOpts, node [32]byte) (string, error) {
+ var (
+ ret0 = new(string)
+ )
+ out := ret0
+ err := _PublicResolver.contract.Call(opts, out, "name", node)
+ return *ret0, err
+}
+
+// Name is a free data retrieval call binding the contract method 0x691f3431.
+//
+// Solidity: function name(bytes32 node) constant returns(string)
+func (_PublicResolver *PublicResolverSession) Name(node [32]byte) (string, error) {
+ return _PublicResolver.Contract.Name(&_PublicResolver.CallOpts, node)
+}
+
+// Name is a free data retrieval call binding the contract method 0x691f3431.
+//
+// Solidity: function name(bytes32 node) constant returns(string)
+func (_PublicResolver *PublicResolverCallerSession) Name(node [32]byte) (string, error) {
+ return _PublicResolver.Contract.Name(&_PublicResolver.CallOpts, node)
+}
+
+// Pubkey is a free data retrieval call binding the contract method 0xc8690233.
+//
+// Solidity: function pubkey(bytes32 node) constant returns(bytes32 x, bytes32 y)
+func (_PublicResolver *PublicResolverCaller) Pubkey(opts *bind.CallOpts, node [32]byte) (struct {
+ X [32]byte
+ Y [32]byte
+}, error) {
+ ret := new(struct {
+ X [32]byte
+ Y [32]byte
+ })
+ out := ret
+ err := _PublicResolver.contract.Call(opts, out, "pubkey", node)
+ return *ret, err
+}
+
+// Pubkey is a free data retrieval call binding the contract method 0xc8690233.
+//
+// Solidity: function pubkey(bytes32 node) constant returns(bytes32 x, bytes32 y)
+func (_PublicResolver *PublicResolverSession) Pubkey(node [32]byte) (struct {
+ X [32]byte
+ Y [32]byte
+}, error) {
+ return _PublicResolver.Contract.Pubkey(&_PublicResolver.CallOpts, node)
+}
+
+// Pubkey is a free data retrieval call binding the contract method 0xc8690233.
+//
+// Solidity: function pubkey(bytes32 node) constant returns(bytes32 x, bytes32 y)
+func (_PublicResolver *PublicResolverCallerSession) Pubkey(node [32]byte) (struct {
+ X [32]byte
+ Y [32]byte
+}, error) {
+ return _PublicResolver.Contract.Pubkey(&_PublicResolver.CallOpts, node)
+}
+
+// SupportsInterface is a free data retrieval call binding the contract method 0x01ffc9a7.
+//
+// Solidity: function supportsInterface(bytes4 interfaceID) constant returns(bool)
+func (_PublicResolver *PublicResolverCaller) SupportsInterface(opts *bind.CallOpts, interfaceID [4]byte) (bool, error) {
+ var (
+ ret0 = new(bool)
+ )
+ out := ret0
+ err := _PublicResolver.contract.Call(opts, out, "supportsInterface", interfaceID)
+ return *ret0, err
+}
+
+// SupportsInterface is a free data retrieval call binding the contract method 0x01ffc9a7.
+//
+// Solidity: function supportsInterface(bytes4 interfaceID) constant returns(bool)
+func (_PublicResolver *PublicResolverSession) SupportsInterface(interfaceID [4]byte) (bool, error) {
+ return _PublicResolver.Contract.SupportsInterface(&_PublicResolver.CallOpts, interfaceID)
+}
+
+// SupportsInterface is a free data retrieval call binding the contract method 0x01ffc9a7.
+//
+// Solidity: function supportsInterface(bytes4 interfaceID) constant returns(bool)
+func (_PublicResolver *PublicResolverCallerSession) SupportsInterface(interfaceID [4]byte) (bool, error) {
+ return _PublicResolver.Contract.SupportsInterface(&_PublicResolver.CallOpts, interfaceID)
+}
+
+// Text is a free data retrieval call binding the contract method 0x59d1d43c.
+//
+// Solidity: function text(bytes32 node, string key) constant returns(string)
+func (_PublicResolver *PublicResolverCaller) Text(opts *bind.CallOpts, node [32]byte, key string) (string, error) {
+ var (
+ ret0 = new(string)
+ )
+ out := ret0
+ err := _PublicResolver.contract.Call(opts, out, "text", node, key)
+ return *ret0, err
+}
+
+// Text is a free data retrieval call binding the contract method 0x59d1d43c.
+//
+// Solidity: function text(bytes32 node, string key) constant returns(string)
+func (_PublicResolver *PublicResolverSession) Text(node [32]byte, key string) (string, error) {
+ return _PublicResolver.Contract.Text(&_PublicResolver.CallOpts, node, key)
+}
+
+// Text is a free data retrieval call binding the contract method 0x59d1d43c.
+//
+// Solidity: function text(bytes32 node, string key) constant returns(string)
+func (_PublicResolver *PublicResolverCallerSession) Text(node [32]byte, key string) (string, error) {
+ return _PublicResolver.Contract.Text(&_PublicResolver.CallOpts, node, key)
+}
+
+// SetABI is a paid mutator transaction binding the contract method 0x623195b0.
+//
+// Solidity: function setABI(bytes32 node, uint256 contentType, bytes data) returns()
+func (_PublicResolver *PublicResolverTransactor) SetABI(opts *bind.TransactOpts, node [32]byte, contentType *big.Int, data []byte) (*types.Transaction, error) {
+ return _PublicResolver.contract.Transact(opts, "setABI", node, contentType, data)
+}
+
+// SetABI is a paid mutator transaction binding the contract method 0x623195b0.
+//
+// Solidity: function setABI(bytes32 node, uint256 contentType, bytes data) returns()
+func (_PublicResolver *PublicResolverSession) SetABI(node [32]byte, contentType *big.Int, data []byte) (*types.Transaction, error) {
+ return _PublicResolver.Contract.SetABI(&_PublicResolver.TransactOpts, node, contentType, data)
+}
+
+// SetABI is a paid mutator transaction binding the contract method 0x623195b0.
+//
+// Solidity: function setABI(bytes32 node, uint256 contentType, bytes data) returns()
+func (_PublicResolver *PublicResolverTransactorSession) SetABI(node [32]byte, contentType *big.Int, data []byte) (*types.Transaction, error) {
+ return _PublicResolver.Contract.SetABI(&_PublicResolver.TransactOpts, node, contentType, data)
+}
+
+// SetAddr is a paid mutator transaction binding the contract method 0xd5fa2b00.
+//
+// Solidity: function setAddr(bytes32 node, address addr) returns()
+func (_PublicResolver *PublicResolverTransactor) SetAddr(opts *bind.TransactOpts, node [32]byte, addr common.Address) (*types.Transaction, error) {
+ return _PublicResolver.contract.Transact(opts, "setAddr", node, addr)
+}
+
+// SetAddr is a paid mutator transaction binding the contract method 0xd5fa2b00.
+//
+// Solidity: function setAddr(bytes32 node, address addr) returns()
+func (_PublicResolver *PublicResolverSession) SetAddr(node [32]byte, addr common.Address) (*types.Transaction, error) {
+ return _PublicResolver.Contract.SetAddr(&_PublicResolver.TransactOpts, node, addr)
+}
+
+// SetAddr is a paid mutator transaction binding the contract method 0xd5fa2b00.
+//
+// Solidity: function setAddr(bytes32 node, address addr) returns()
+func (_PublicResolver *PublicResolverTransactorSession) SetAddr(node [32]byte, addr common.Address) (*types.Transaction, error) {
+ return _PublicResolver.Contract.SetAddr(&_PublicResolver.TransactOpts, node, addr)
+}
+
+// SetContenthash is a paid mutator transaction binding the contract method 0x304e6ade.
+//
+// Solidity: function setContenthash(bytes32 node, bytes hash) returns()
+func (_PublicResolver *PublicResolverTransactor) SetContenthash(opts *bind.TransactOpts, node [32]byte, hash []byte) (*types.Transaction, error) {
+ return _PublicResolver.contract.Transact(opts, "setContenthash", node, hash)
+}
+
+// SetContenthash is a paid mutator transaction binding the contract method 0x304e6ade.
+//
+// Solidity: function setContenthash(bytes32 node, bytes hash) returns()
+func (_PublicResolver *PublicResolverSession) SetContenthash(node [32]byte, hash []byte) (*types.Transaction, error) {
+ return _PublicResolver.Contract.SetContenthash(&_PublicResolver.TransactOpts, node, hash)
+}
+
+// SetContenthash is a paid mutator transaction binding the contract method 0x304e6ade.
+//
+// Solidity: function setContenthash(bytes32 node, bytes hash) returns()
+func (_PublicResolver *PublicResolverTransactorSession) SetContenthash(node [32]byte, hash []byte) (*types.Transaction, error) {
+ return _PublicResolver.Contract.SetContenthash(&_PublicResolver.TransactOpts, node, hash)
+}
+
+// SetName is a paid mutator transaction binding the contract method 0x77372213.
+//
+// Solidity: function setName(bytes32 node, string name) returns()
+func (_PublicResolver *PublicResolverTransactor) SetName(opts *bind.TransactOpts, node [32]byte, name string) (*types.Transaction, error) {
+ return _PublicResolver.contract.Transact(opts, "setName", node, name)
+}
+
+// SetName is a paid mutator transaction binding the contract method 0x77372213.
+//
+// Solidity: function setName(bytes32 node, string name) returns()
+func (_PublicResolver *PublicResolverSession) SetName(node [32]byte, name string) (*types.Transaction, error) {
+ return _PublicResolver.Contract.SetName(&_PublicResolver.TransactOpts, node, name)
+}
+
+// SetName is a paid mutator transaction binding the contract method 0x77372213.
+//
+// Solidity: function setName(bytes32 node, string name) returns()
+func (_PublicResolver *PublicResolverTransactorSession) SetName(node [32]byte, name string) (*types.Transaction, error) {
+ return _PublicResolver.Contract.SetName(&_PublicResolver.TransactOpts, node, name)
+}
+
+// SetPubkey is a paid mutator transaction binding the contract method 0x29cd62ea.
+//
+// Solidity: function setPubkey(bytes32 node, bytes32 x, bytes32 y) returns()
+func (_PublicResolver *PublicResolverTransactor) SetPubkey(opts *bind.TransactOpts, node [32]byte, x [32]byte, y [32]byte) (*types.Transaction, error) {
+ return _PublicResolver.contract.Transact(opts, "setPubkey", node, x, y)
+}
+
+// SetPubkey is a paid mutator transaction binding the contract method 0x29cd62ea.
+//
+// Solidity: function setPubkey(bytes32 node, bytes32 x, bytes32 y) returns()
+func (_PublicResolver *PublicResolverSession) SetPubkey(node [32]byte, x [32]byte, y [32]byte) (*types.Transaction, error) {
+ return _PublicResolver.Contract.SetPubkey(&_PublicResolver.TransactOpts, node, x, y)
+}
+
+// SetPubkey is a paid mutator transaction binding the contract method 0x29cd62ea.
+//
+// Solidity: function setPubkey(bytes32 node, bytes32 x, bytes32 y) returns()
+func (_PublicResolver *PublicResolverTransactorSession) SetPubkey(node [32]byte, x [32]byte, y [32]byte) (*types.Transaction, error) {
+ return _PublicResolver.Contract.SetPubkey(&_PublicResolver.TransactOpts, node, x, y)
+}
+
+// SetText is a paid mutator transaction binding the contract method 0x10f13a8c.
+//
+// Solidity: function setText(bytes32 node, string key, string value) returns()
+func (_PublicResolver *PublicResolverTransactor) SetText(opts *bind.TransactOpts, node [32]byte, key string, value string) (*types.Transaction, error) {
+ return _PublicResolver.contract.Transact(opts, "setText", node, key, value)
+}
+
+// SetText is a paid mutator transaction binding the contract method 0x10f13a8c.
+//
+// Solidity: function setText(bytes32 node, string key, string value) returns()
+func (_PublicResolver *PublicResolverSession) SetText(node [32]byte, key string, value string) (*types.Transaction, error) {
+ return _PublicResolver.Contract.SetText(&_PublicResolver.TransactOpts, node, key, value)
+}
+
+// SetText is a paid mutator transaction binding the contract method 0x10f13a8c.
+//
+// Solidity: function setText(bytes32 node, string key, string value) returns()
+func (_PublicResolver *PublicResolverTransactorSession) SetText(node [32]byte, key string, value string) (*types.Transaction, error) {
+ return _PublicResolver.Contract.SetText(&_PublicResolver.TransactOpts, node, key, value)
+}
+
+// PublicResolverABIChangedIterator is returned from FilterABIChanged and is used to iterate over the raw logs and unpacked data for ABIChanged events raised by the PublicResolver contract.
+type PublicResolverABIChangedIterator struct {
+ Event *PublicResolverABIChanged // Event containing the contract specifics and raw log
+
+ contract *bind.BoundContract // Generic contract to use for unpacking event data
+ event string // Event name to use for unpacking event data
+
+ logs chan types.Log // Log channel receiving the found contract events
+ sub ethereum.Subscription // Subscription for errors, completion and termination
+ done bool // Whether the subscription completed delivering logs
+ fail error // Occurred error to stop iteration
+}
+
+// Next advances the iterator to the subsequent event, returning whether there
+// are any more events found. In case of a retrieval or parsing error, false is
+// returned and Error() can be queried for the exact failure.
+func (it *PublicResolverABIChangedIterator) Next() bool {
+ // If the iterator failed, stop iterating
+ if it.fail != nil {
+ return false
+ }
+ // If the iterator completed, deliver directly whatever's available
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(PublicResolverABIChanged)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+ // Iterator still in progress, wait for either a data or an error event
+ select {
+ case log := <-it.logs:
+ it.Event = new(PublicResolverABIChanged)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+// Error returns any retrieval or parsing error occurred during filtering.
+func (it *PublicResolverABIChangedIterator) Error() error {
+ return it.fail
+}
+
+// Close terminates the iteration process, releasing any pending underlying
+// resources.
+func (it *PublicResolverABIChangedIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+// PublicResolverABIChanged represents a ABIChanged event raised by the PublicResolver contract.
+type PublicResolverABIChanged struct {
+ Node [32]byte
+ ContentType *big.Int
+ Raw types.Log // Blockchain specific contextual infos
+}
+
+// FilterABIChanged is a free log retrieval operation binding the contract event 0xaa121bbeef5f32f5961a2a28966e769023910fc9479059ee3495d4c1a696efe3.
+//
+// Solidity: event ABIChanged(bytes32 indexed node, uint256 indexed contentType)
+func (_PublicResolver *PublicResolverFilterer) FilterABIChanged(opts *bind.FilterOpts, node [][32]byte, contentType []*big.Int) (*PublicResolverABIChangedIterator, error) {
+
+ var nodeRule []interface{}
+ for _, nodeItem := range node {
+ nodeRule = append(nodeRule, nodeItem)
+ }
+ var contentTypeRule []interface{}
+ for _, contentTypeItem := range contentType {
+ contentTypeRule = append(contentTypeRule, contentTypeItem)
+ }
+
+ logs, sub, err := _PublicResolver.contract.FilterLogs(opts, "ABIChanged", nodeRule, contentTypeRule)
+ if err != nil {
+ return nil, err
+ }
+ return &PublicResolverABIChangedIterator{contract: _PublicResolver.contract, event: "ABIChanged", logs: logs, sub: sub}, nil
+}
+
+// WatchABIChanged is a free log subscription operation binding the contract event 0xaa121bbeef5f32f5961a2a28966e769023910fc9479059ee3495d4c1a696efe3.
+//
+// Solidity: event ABIChanged(bytes32 indexed node, uint256 indexed contentType)
+func (_PublicResolver *PublicResolverFilterer) WatchABIChanged(opts *bind.WatchOpts, sink chan<- *PublicResolverABIChanged, node [][32]byte, contentType []*big.Int) (event.Subscription, error) {
+
+ var nodeRule []interface{}
+ for _, nodeItem := range node {
+ nodeRule = append(nodeRule, nodeItem)
+ }
+ var contentTypeRule []interface{}
+ for _, contentTypeItem := range contentType {
+ contentTypeRule = append(contentTypeRule, contentTypeItem)
+ }
+
+ logs, sub, err := _PublicResolver.contract.WatchLogs(opts, "ABIChanged", nodeRule, contentTypeRule)
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+ // New log arrived, parse the event and forward to the user
+ event := new(PublicResolverABIChanged)
+ if err := _PublicResolver.contract.UnpackLog(event, "ABIChanged", log); err != nil {
+ return err
+ }
+ event.Raw = log
+
+ select {
+ case sink <- event:
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ }
+ }), nil
+}
+
+// PublicResolverAddrChangedIterator is returned from FilterAddrChanged and is used to iterate over the raw logs and unpacked data for AddrChanged events raised by the PublicResolver contract.
+type PublicResolverAddrChangedIterator struct {
+ Event *PublicResolverAddrChanged // Event containing the contract specifics and raw log
+
+ contract *bind.BoundContract // Generic contract to use for unpacking event data
+ event string // Event name to use for unpacking event data
+
+ logs chan types.Log // Log channel receiving the found contract events
+ sub ethereum.Subscription // Subscription for errors, completion and termination
+ done bool // Whether the subscription completed delivering logs
+ fail error // Occurred error to stop iteration
+}
+
+// Next advances the iterator to the subsequent event, returning whether there
+// are any more events found. In case of a retrieval or parsing error, false is
+// returned and Error() can be queried for the exact failure.
+func (it *PublicResolverAddrChangedIterator) Next() bool {
+ // If the iterator failed, stop iterating
+ if it.fail != nil {
+ return false
+ }
+ // If the iterator completed, deliver directly whatever's available
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(PublicResolverAddrChanged)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+ // Iterator still in progress, wait for either a data or an error event
+ select {
+ case log := <-it.logs:
+ it.Event = new(PublicResolverAddrChanged)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+// Error returns any retrieval or parsing error occurred during filtering.
+func (it *PublicResolverAddrChangedIterator) Error() error {
+ return it.fail
+}
+
+// Close terminates the iteration process, releasing any pending underlying
+// resources.
+func (it *PublicResolverAddrChangedIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+// PublicResolverAddrChanged represents a AddrChanged event raised by the PublicResolver contract.
+type PublicResolverAddrChanged struct {
+ Node [32]byte
+ A common.Address
+ Raw types.Log // Blockchain specific contextual infos
+}
+
+// FilterAddrChanged is a free log retrieval operation binding the contract event 0x52d7d861f09ab3d26239d492e8968629f95e9e318cf0b73bfddc441522a15fd2.
+//
+// Solidity: event AddrChanged(bytes32 indexed node, address a)
+func (_PublicResolver *PublicResolverFilterer) FilterAddrChanged(opts *bind.FilterOpts, node [][32]byte) (*PublicResolverAddrChangedIterator, error) {
+
+ var nodeRule []interface{}
+ for _, nodeItem := range node {
+ nodeRule = append(nodeRule, nodeItem)
+ }
+
+ logs, sub, err := _PublicResolver.contract.FilterLogs(opts, "AddrChanged", nodeRule)
+ if err != nil {
+ return nil, err
+ }
+ return &PublicResolverAddrChangedIterator{contract: _PublicResolver.contract, event: "AddrChanged", logs: logs, sub: sub}, nil
+}
+
+// WatchAddrChanged is a free log subscription operation binding the contract event 0x52d7d861f09ab3d26239d492e8968629f95e9e318cf0b73bfddc441522a15fd2.
+//
+// Solidity: event AddrChanged(bytes32 indexed node, address a)
+func (_PublicResolver *PublicResolverFilterer) WatchAddrChanged(opts *bind.WatchOpts, sink chan<- *PublicResolverAddrChanged, node [][32]byte) (event.Subscription, error) {
+
+ var nodeRule []interface{}
+ for _, nodeItem := range node {
+ nodeRule = append(nodeRule, nodeItem)
+ }
+
+ logs, sub, err := _PublicResolver.contract.WatchLogs(opts, "AddrChanged", nodeRule)
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+ // New log arrived, parse the event and forward to the user
+ event := new(PublicResolverAddrChanged)
+ if err := _PublicResolver.contract.UnpackLog(event, "AddrChanged", log); err != nil {
+ return err
+ }
+ event.Raw = log
+
+ select {
+ case sink <- event:
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ }
+ }), nil
+}
+
+// PublicResolverContenthashChangedIterator is returned from FilterContenthashChanged and is used to iterate over the raw logs and unpacked data for ContenthashChanged events raised by the PublicResolver contract.
+type PublicResolverContenthashChangedIterator struct {
+ Event *PublicResolverContenthashChanged // Event containing the contract specifics and raw log
+
+ contract *bind.BoundContract // Generic contract to use for unpacking event data
+ event string // Event name to use for unpacking event data
+
+ logs chan types.Log // Log channel receiving the found contract events
+ sub ethereum.Subscription // Subscription for errors, completion and termination
+ done bool // Whether the subscription completed delivering logs
+ fail error // Occurred error to stop iteration
+}
+
+// Next advances the iterator to the subsequent event, returning whether there
+// are any more events found. In case of a retrieval or parsing error, false is
+// returned and Error() can be queried for the exact failure.
+func (it *PublicResolverContenthashChangedIterator) Next() bool {
+ // If the iterator failed, stop iterating
+ if it.fail != nil {
+ return false
+ }
+ // If the iterator completed, deliver directly whatever's available
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(PublicResolverContenthashChanged)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+ // Iterator still in progress, wait for either a data or an error event
+ select {
+ case log := <-it.logs:
+ it.Event = new(PublicResolverContenthashChanged)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+// Error returns any retrieval or parsing error occurred during filtering.
+func (it *PublicResolverContenthashChangedIterator) Error() error {
+ return it.fail
+}
+
+// Close terminates the iteration process, releasing any pending underlying
+// resources.
+func (it *PublicResolverContenthashChangedIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+// PublicResolverContenthashChanged represents a ContenthashChanged event raised by the PublicResolver contract.
+type PublicResolverContenthashChanged struct {
+ Node [32]byte
+ Hash []byte
+ Raw types.Log // Blockchain specific contextual infos
+}
+
+// FilterContenthashChanged is a free log retrieval operation binding the contract event 0xe379c1624ed7e714cc0937528a32359d69d5281337765313dba4e081b72d7578.
+//
+// Solidity: event ContenthashChanged(bytes32 indexed node, bytes hash)
+func (_PublicResolver *PublicResolverFilterer) FilterContenthashChanged(opts *bind.FilterOpts, node [][32]byte) (*PublicResolverContenthashChangedIterator, error) {
+
+ var nodeRule []interface{}
+ for _, nodeItem := range node {
+ nodeRule = append(nodeRule, nodeItem)
+ }
+
+ logs, sub, err := _PublicResolver.contract.FilterLogs(opts, "ContenthashChanged", nodeRule)
+ if err != nil {
+ return nil, err
+ }
+ return &PublicResolverContenthashChangedIterator{contract: _PublicResolver.contract, event: "ContenthashChanged", logs: logs, sub: sub}, nil
+}
+
+// WatchContenthashChanged is a free log subscription operation binding the contract event 0xe379c1624ed7e714cc0937528a32359d69d5281337765313dba4e081b72d7578.
+//
+// Solidity: event ContenthashChanged(bytes32 indexed node, bytes hash)
+func (_PublicResolver *PublicResolverFilterer) WatchContenthashChanged(opts *bind.WatchOpts, sink chan<- *PublicResolverContenthashChanged, node [][32]byte) (event.Subscription, error) {
+
+ var nodeRule []interface{}
+ for _, nodeItem := range node {
+ nodeRule = append(nodeRule, nodeItem)
+ }
+
+ logs, sub, err := _PublicResolver.contract.WatchLogs(opts, "ContenthashChanged", nodeRule)
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+ // New log arrived, parse the event and forward to the user
+ event := new(PublicResolverContenthashChanged)
+ if err := _PublicResolver.contract.UnpackLog(event, "ContenthashChanged", log); err != nil {
+ return err
+ }
+ event.Raw = log
+
+ select {
+ case sink <- event:
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ }
+ }), nil
+}
+
+// PublicResolverNameChangedIterator is returned from FilterNameChanged and is used to iterate over the raw logs and unpacked data for NameChanged events raised by the PublicResolver contract.
+type PublicResolverNameChangedIterator struct {
+ Event *PublicResolverNameChanged // Event containing the contract specifics and raw log
+
+ contract *bind.BoundContract // Generic contract to use for unpacking event data
+ event string // Event name to use for unpacking event data
+
+ logs chan types.Log // Log channel receiving the found contract events
+ sub ethereum.Subscription // Subscription for errors, completion and termination
+ done bool // Whether the subscription completed delivering logs
+ fail error // Occurred error to stop iteration
+}
+
+// Next advances the iterator to the subsequent event, returning whether there
+// are any more events found. In case of a retrieval or parsing error, false is
+// returned and Error() can be queried for the exact failure.
+func (it *PublicResolverNameChangedIterator) Next() bool {
+ // If the iterator failed, stop iterating
+ if it.fail != nil {
+ return false
+ }
+ // If the iterator completed, deliver directly whatever's available
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(PublicResolverNameChanged)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+ // Iterator still in progress, wait for either a data or an error event
+ select {
+ case log := <-it.logs:
+ it.Event = new(PublicResolverNameChanged)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+// Error returns any retrieval or parsing error occurred during filtering.
+func (it *PublicResolverNameChangedIterator) Error() error {
+ return it.fail
+}
+
+// Close terminates the iteration process, releasing any pending underlying
+// resources.
+func (it *PublicResolverNameChangedIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+// PublicResolverNameChanged represents a NameChanged event raised by the PublicResolver contract.
+type PublicResolverNameChanged struct {
+ Node [32]byte
+ Name string
+ Raw types.Log // Blockchain specific contextual infos
+}
+
+// FilterNameChanged is a free log retrieval operation binding the contract event 0xb7d29e911041e8d9b843369e890bcb72c9388692ba48b65ac54e7214c4c348f7.
+//
+// Solidity: event NameChanged(bytes32 indexed node, string name)
+func (_PublicResolver *PublicResolverFilterer) FilterNameChanged(opts *bind.FilterOpts, node [][32]byte) (*PublicResolverNameChangedIterator, error) {
+
+ var nodeRule []interface{}
+ for _, nodeItem := range node {
+ nodeRule = append(nodeRule, nodeItem)
+ }
+
+ logs, sub, err := _PublicResolver.contract.FilterLogs(opts, "NameChanged", nodeRule)
+ if err != nil {
+ return nil, err
+ }
+ return &PublicResolverNameChangedIterator{contract: _PublicResolver.contract, event: "NameChanged", logs: logs, sub: sub}, nil
+}
+
+// WatchNameChanged is a free log subscription operation binding the contract event 0xb7d29e911041e8d9b843369e890bcb72c9388692ba48b65ac54e7214c4c348f7.
+//
+// Solidity: event NameChanged(bytes32 indexed node, string name)
+func (_PublicResolver *PublicResolverFilterer) WatchNameChanged(opts *bind.WatchOpts, sink chan<- *PublicResolverNameChanged, node [][32]byte) (event.Subscription, error) {
+
+ var nodeRule []interface{}
+ for _, nodeItem := range node {
+ nodeRule = append(nodeRule, nodeItem)
+ }
+
+ logs, sub, err := _PublicResolver.contract.WatchLogs(opts, "NameChanged", nodeRule)
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+ // New log arrived, parse the event and forward to the user
+ event := new(PublicResolverNameChanged)
+ if err := _PublicResolver.contract.UnpackLog(event, "NameChanged", log); err != nil {
+ return err
+ }
+ event.Raw = log
+
+ select {
+ case sink <- event:
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ }
+ }), nil
+}
+
+// PublicResolverPubkeyChangedIterator is returned from FilterPubkeyChanged and is used to iterate over the raw logs and unpacked data for PubkeyChanged events raised by the PublicResolver contract.
+type PublicResolverPubkeyChangedIterator struct {
+ Event *PublicResolverPubkeyChanged // Event containing the contract specifics and raw log
+
+ contract *bind.BoundContract // Generic contract to use for unpacking event data
+ event string // Event name to use for unpacking event data
+
+ logs chan types.Log // Log channel receiving the found contract events
+ sub ethereum.Subscription // Subscription for errors, completion and termination
+ done bool // Whether the subscription completed delivering logs
+ fail error // Occurred error to stop iteration
+}
+
+// Next advances the iterator to the subsequent event, returning whether there
+// are any more events found. In case of a retrieval or parsing error, false is
+// returned and Error() can be queried for the exact failure.
+func (it *PublicResolverPubkeyChangedIterator) Next() bool {
+ // If the iterator failed, stop iterating
+ if it.fail != nil {
+ return false
+ }
+ // If the iterator completed, deliver directly whatever's available
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(PublicResolverPubkeyChanged)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+ // Iterator still in progress, wait for either a data or an error event
+ select {
+ case log := <-it.logs:
+ it.Event = new(PublicResolverPubkeyChanged)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+// Error returns any retrieval or parsing error occurred during filtering.
+func (it *PublicResolverPubkeyChangedIterator) Error() error {
+ return it.fail
+}
+
+// Close terminates the iteration process, releasing any pending underlying
+// resources.
+func (it *PublicResolverPubkeyChangedIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+// PublicResolverPubkeyChanged represents a PubkeyChanged event raised by the PublicResolver contract.
+type PublicResolverPubkeyChanged struct {
+ Node [32]byte
+ X [32]byte
+ Y [32]byte
+ Raw types.Log // Blockchain specific contextual infos
+}
+
+// FilterPubkeyChanged is a free log retrieval operation binding the contract event 0x1d6f5e03d3f63eb58751986629a5439baee5079ff04f345becb66e23eb154e46.
+//
+// Solidity: event PubkeyChanged(bytes32 indexed node, bytes32 x, bytes32 y)
+func (_PublicResolver *PublicResolverFilterer) FilterPubkeyChanged(opts *bind.FilterOpts, node [][32]byte) (*PublicResolverPubkeyChangedIterator, error) {
+
+ var nodeRule []interface{}
+ for _, nodeItem := range node {
+ nodeRule = append(nodeRule, nodeItem)
+ }
+
+ logs, sub, err := _PublicResolver.contract.FilterLogs(opts, "PubkeyChanged", nodeRule)
+ if err != nil {
+ return nil, err
+ }
+ return &PublicResolverPubkeyChangedIterator{contract: _PublicResolver.contract, event: "PubkeyChanged", logs: logs, sub: sub}, nil
+}
+
+// WatchPubkeyChanged is a free log subscription operation binding the contract event 0x1d6f5e03d3f63eb58751986629a5439baee5079ff04f345becb66e23eb154e46.
+//
+// Solidity: event PubkeyChanged(bytes32 indexed node, bytes32 x, bytes32 y)
+func (_PublicResolver *PublicResolverFilterer) WatchPubkeyChanged(opts *bind.WatchOpts, sink chan<- *PublicResolverPubkeyChanged, node [][32]byte) (event.Subscription, error) {
+
+ var nodeRule []interface{}
+ for _, nodeItem := range node {
+ nodeRule = append(nodeRule, nodeItem)
+ }
+
+ logs, sub, err := _PublicResolver.contract.WatchLogs(opts, "PubkeyChanged", nodeRule)
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+ // New log arrived, parse the event and forward to the user
+ event := new(PublicResolverPubkeyChanged)
+ if err := _PublicResolver.contract.UnpackLog(event, "PubkeyChanged", log); err != nil {
+ return err
+ }
+ event.Raw = log
+
+ select {
+ case sink <- event:
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ }
+ }), nil
+}
+
+// PublicResolverTextChangedIterator is returned from FilterTextChanged and is used to iterate over the raw logs and unpacked data for TextChanged events raised by the PublicResolver contract.
+type PublicResolverTextChangedIterator struct {
+ Event *PublicResolverTextChanged // Event containing the contract specifics and raw log
+
+ contract *bind.BoundContract // Generic contract to use for unpacking event data
+ event string // Event name to use for unpacking event data
+
+ logs chan types.Log // Log channel receiving the found contract events
+ sub ethereum.Subscription // Subscription for errors, completion and termination
+ done bool // Whether the subscription completed delivering logs
+ fail error // Occurred error to stop iteration
+}
+
+// Next advances the iterator to the subsequent event, returning whether there
+// are any more events found. In case of a retrieval or parsing error, false is
+// returned and Error() can be queried for the exact failure.
+func (it *PublicResolverTextChangedIterator) Next() bool {
+ // If the iterator failed, stop iterating
+ if it.fail != nil {
+ return false
+ }
+ // If the iterator completed, deliver directly whatever's available
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(PublicResolverTextChanged)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+ // Iterator still in progress, wait for either a data or an error event
+ select {
+ case log := <-it.logs:
+ it.Event = new(PublicResolverTextChanged)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+// Error returns any retrieval or parsing error occurred during filtering.
+func (it *PublicResolverTextChangedIterator) Error() error {
+ return it.fail
+}
+
+// Close terminates the iteration process, releasing any pending underlying
+// resources.
+func (it *PublicResolverTextChangedIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+// PublicResolverTextChanged represents a TextChanged event raised by the PublicResolver contract.
+type PublicResolverTextChanged struct {
+ Node [32]byte
+ IndexedKey string
+ Key string
+ Raw types.Log // Blockchain specific contextual infos
+}
+
+// FilterTextChanged is a free log retrieval operation binding the contract event 0xd8c9334b1a9c2f9da342a0a2b32629c1a229b6445dad78947f674b44444a7550.
+//
+// Solidity: event TextChanged(bytes32 indexed node, string indexedKey, string key)
+func (_PublicResolver *PublicResolverFilterer) FilterTextChanged(opts *bind.FilterOpts, node [][32]byte) (*PublicResolverTextChangedIterator, error) {
+
+ var nodeRule []interface{}
+ for _, nodeItem := range node {
+ nodeRule = append(nodeRule, nodeItem)
+ }
+
+ logs, sub, err := _PublicResolver.contract.FilterLogs(opts, "TextChanged", nodeRule)
+ if err != nil {
+ return nil, err
+ }
+ return &PublicResolverTextChangedIterator{contract: _PublicResolver.contract, event: "TextChanged", logs: logs, sub: sub}, nil
+}
+
+// WatchTextChanged is a free log subscription operation binding the contract event 0xd8c9334b1a9c2f9da342a0a2b32629c1a229b6445dad78947f674b44444a7550.
+//
+// Solidity: event TextChanged(bytes32 indexed node, string indexedKey, string key)
+func (_PublicResolver *PublicResolverFilterer) WatchTextChanged(opts *bind.WatchOpts, sink chan<- *PublicResolverTextChanged, node [][32]byte) (event.Subscription, error) {
+
+ var nodeRule []interface{}
+ for _, nodeItem := range node {
+ nodeRule = append(nodeRule, nodeItem)
+ }
+
+ logs, sub, err := _PublicResolver.contract.WatchLogs(opts, "TextChanged", nodeRule)
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+ // New log arrived, parse the event and forward to the user
+ event := new(PublicResolverTextChanged)
+ if err := _PublicResolver.contract.UnpackLog(event, "TextChanged", log); err != nil {
+ return err
+ }
+ event.Raw = log
+
+ select {
+ case sink <- event:
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ }
+ }), nil
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/contracts/ens/ens.go b/vendor/github.com/ethereum/go-ethereum/contracts/ens/ens.go
new file mode 100644
index 00000000..6fed172d
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/contracts/ens/ens.go
@@ -0,0 +1,263 @@
+// Copyright 2016 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+package ens
+
+//go:generate abigen --sol contract/ENS.sol --pkg contract --out contract/ens.go
+//go:generate abigen --sol contract/ENSRegistry.sol --exc contract/ENS.sol:ENS --pkg contract --out contract/ensregistry.go
+//go:generate abigen --sol contract/FIFSRegistrar.sol --exc contract/ENS.sol:ENS --pkg contract --out contract/fifsregistrar.go
+//go:generate abigen --sol contract/PublicResolver.sol --exc contract/ENS.sol:ENS --pkg contract --out contract/publicresolver.go
+
+import (
+ "encoding/binary"
+ "strings"
+
+ "github.com/ethereum/go-ethereum/accounts/abi/bind"
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/contracts/ens/contract"
+ "github.com/ethereum/go-ethereum/contracts/ens/fallback_contract"
+ "github.com/ethereum/go-ethereum/core/types"
+ "github.com/ethereum/go-ethereum/crypto"
+)
+
+var (
+ MainNetAddress = common.HexToAddress("0x314159265dD8dbb310642f98f50C066173C1259b")
+ TestNetAddress = common.HexToAddress("0x112234455c3a32fd11230c42e7bccd4a84e02010")
+ contentHash_Interface_Id [4]byte
+)
+
+const contentHash_Interface_Id_Spec = 0xbc1c58d1
+
+func init() {
+ binary.BigEndian.PutUint32(contentHash_Interface_Id[:], contentHash_Interface_Id_Spec)
+}
+
+// ENS is the swarm domain name registry and resolver
+type ENS struct {
+ *contract.ENSSession
+ contractBackend bind.ContractBackend
+}
+
+// NewENS creates a struct exposing convenient high-level operations for interacting with
+// the Ethereum Name Service.
+func NewENS(transactOpts *bind.TransactOpts, contractAddr common.Address, contractBackend bind.ContractBackend) (*ENS, error) {
+ ens, err := contract.NewENS(contractAddr, contractBackend)
+ if err != nil {
+ return nil, err
+ }
+ return &ENS{
+ &contract.ENSSession{
+ Contract: ens,
+ TransactOpts: *transactOpts,
+ },
+ contractBackend,
+ }, nil
+}
+
+// DeployENS deploys an instance of the ENS nameservice, with a 'first-in, first-served' root registrar.
+func DeployENS(transactOpts *bind.TransactOpts, contractBackend bind.ContractBackend) (common.Address, *ENS, error) {
+ // Deploy the ENS registry
+ ensAddr, _, _, err := contract.DeployENSRegistry(transactOpts, contractBackend)
+ if err != nil {
+ return ensAddr, nil, err
+ }
+ ens, err := NewENS(transactOpts, ensAddr, contractBackend)
+ if err != nil {
+ return ensAddr, nil, err
+ }
+ // Deploy the registrar
+ regAddr, _, _, err := contract.DeployFIFSRegistrar(transactOpts, contractBackend, ensAddr, [32]byte{})
+ if err != nil {
+ return ensAddr, nil, err
+ }
+ // Set the registrar as owner of the ENS root
+ if _, err = ens.SetOwner([32]byte{}, regAddr); err != nil {
+ return ensAddr, nil, err
+ }
+ return ensAddr, ens, nil
+}
+
+func ensParentNode(name string) (common.Hash, common.Hash) {
+ parts := strings.SplitN(name, ".", 2)
+ label := crypto.Keccak256Hash([]byte(parts[0]))
+ if len(parts) == 1 {
+ return [32]byte{}, label
+ }
+ parentNode, parentLabel := ensParentNode(parts[1])
+ return crypto.Keccak256Hash(parentNode[:], parentLabel[:]), label
+}
+
+func EnsNode(name string) common.Hash {
+ parentNode, parentLabel := ensParentNode(name)
+ return crypto.Keccak256Hash(parentNode[:], parentLabel[:])
+}
+
+func (ens *ENS) getResolver(node [32]byte) (*contract.PublicResolverSession, error) {
+ resolverAddr, err := ens.Resolver(node)
+ if err != nil {
+ return nil, err
+ }
+ resolver, err := contract.NewPublicResolver(resolverAddr, ens.contractBackend)
+ if err != nil {
+ return nil, err
+ }
+ return &contract.PublicResolverSession{
+ Contract: resolver,
+ TransactOpts: ens.TransactOpts,
+ }, nil
+}
+
+func (ens *ENS) getFallbackResolver(node [32]byte) (*fallback_contract.PublicResolverSession, error) {
+ resolverAddr, err := ens.Resolver(node)
+ if err != nil {
+ return nil, err
+ }
+ resolver, err := fallback_contract.NewPublicResolver(resolverAddr, ens.contractBackend)
+ if err != nil {
+ return nil, err
+ }
+ return &fallback_contract.PublicResolverSession{
+ Contract: resolver,
+ TransactOpts: ens.TransactOpts,
+ }, nil
+}
+
+func (ens *ENS) getRegistrar(node [32]byte) (*contract.FIFSRegistrarSession, error) {
+ registrarAddr, err := ens.Owner(node)
+ if err != nil {
+ return nil, err
+ }
+ registrar, err := contract.NewFIFSRegistrar(registrarAddr, ens.contractBackend)
+ if err != nil {
+ return nil, err
+ }
+ return &contract.FIFSRegistrarSession{
+ Contract: registrar,
+ TransactOpts: ens.TransactOpts,
+ }, nil
+}
+
+// Resolve is a non-transactional call that returns the content hash associated with a name.
+func (ens *ENS) Resolve(name string) (common.Hash, error) {
+ node := EnsNode(name)
+
+ resolver, err := ens.getResolver(node)
+ if err != nil {
+ return common.Hash{}, err
+ }
+
+ // IMPORTANT: The old contract is deprecated. This code should be removed latest on June 1st 2019
+ supported, err := resolver.SupportsInterface(contentHash_Interface_Id)
+ if err != nil {
+ return common.Hash{}, err
+ }
+
+ if !supported {
+ resolver, err := ens.getFallbackResolver(node)
+ if err != nil {
+ return common.Hash{}, err
+ }
+ ret, err := resolver.Content(node)
+ if err != nil {
+ return common.Hash{}, err
+ }
+ return common.BytesToHash(ret[:]), nil
+ }
+
+ // END DEPRECATED CODE
+
+ contentHash, err := resolver.Contenthash(node)
+ if err != nil {
+ return common.Hash{}, err
+ }
+
+ return extractContentHash(contentHash)
+}
+
+// Addr is a non-transactional call that returns the address associated with a name.
+func (ens *ENS) Addr(name string) (common.Address, error) {
+ node := EnsNode(name)
+
+ resolver, err := ens.getResolver(node)
+ if err != nil {
+ return common.Address{}, err
+ }
+ ret, err := resolver.Addr(node)
+ if err != nil {
+ return common.Address{}, err
+ }
+ return common.BytesToAddress(ret[:]), nil
+}
+
+// SetAddress sets the address associated with a name. Only works if the caller
+// owns the name, and the associated resolver implements a `setAddress` function.
+func (ens *ENS) SetAddr(name string, addr common.Address) (*types.Transaction, error) {
+ node := EnsNode(name)
+
+ resolver, err := ens.getResolver(node)
+ if err != nil {
+ return nil, err
+ }
+ opts := ens.TransactOpts
+ opts.GasLimit = 200000
+ return resolver.Contract.SetAddr(&opts, node, addr)
+}
+
+// Register registers a new domain name for the caller, making them the owner of the new name.
+// Only works if the registrar for the parent domain implements the FIFS registrar protocol.
+func (ens *ENS) Register(name string) (*types.Transaction, error) {
+ parentNode, label := ensParentNode(name)
+ registrar, err := ens.getRegistrar(parentNode)
+ if err != nil {
+ return nil, err
+ }
+ return registrar.Contract.Register(&ens.TransactOpts, label, ens.TransactOpts.From)
+}
+
+// SetContentHash sets the content hash associated with a name. Only works if the caller
+// owns the name, and the associated resolver implements a `setContenthash` function.
+func (ens *ENS) SetContentHash(name string, hash []byte) (*types.Transaction, error) {
+ node := EnsNode(name)
+
+ resolver, err := ens.getResolver(node)
+ if err != nil {
+ return nil, err
+ }
+
+ opts := ens.TransactOpts
+ opts.GasLimit = 200000
+
+ // IMPORTANT: The old contract is deprecated. This code should be removed latest on June 1st 2019
+ supported, err := resolver.SupportsInterface(contentHash_Interface_Id)
+ if err != nil {
+ return nil, err
+ }
+
+ if !supported {
+ resolver, err := ens.getFallbackResolver(node)
+ if err != nil {
+ return nil, err
+ }
+ opts := ens.TransactOpts
+ opts.GasLimit = 200000
+ var b [32]byte
+ copy(b[:], hash)
+ return resolver.Contract.SetContent(&opts, node, b)
+ }
+
+ // END DEPRECATED CODE
+ return resolver.Contract.SetContenthash(&opts, node, hash)
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/contracts/ens/fallback_contract/PublicResolver.sol b/vendor/github.com/ethereum/go-ethereum/contracts/ens/fallback_contract/PublicResolver.sol
new file mode 100644
index 00000000..9dcc9568
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/contracts/ens/fallback_contract/PublicResolver.sol
@@ -0,0 +1,212 @@
+pragma solidity ^0.4.0;
+
+import './AbstractENS.sol';
+
+/**
+ * A simple resolver anyone can use; only allows the owner of a node to set its
+ * address.
+ */
+contract PublicResolver {
+ bytes4 constant INTERFACE_META_ID = 0x01ffc9a7;
+ bytes4 constant ADDR_INTERFACE_ID = 0x3b3b57de;
+ bytes4 constant CONTENT_INTERFACE_ID = 0xd8389dc5;
+ bytes4 constant NAME_INTERFACE_ID = 0x691f3431;
+ bytes4 constant ABI_INTERFACE_ID = 0x2203ab56;
+ bytes4 constant PUBKEY_INTERFACE_ID = 0xc8690233;
+ bytes4 constant TEXT_INTERFACE_ID = 0x59d1d43c;
+
+ event AddrChanged(bytes32 indexed node, address a);
+ event ContentChanged(bytes32 indexed node, bytes32 hash);
+ event NameChanged(bytes32 indexed node, string name);
+ event ABIChanged(bytes32 indexed node, uint256 indexed contentType);
+ event PubkeyChanged(bytes32 indexed node, bytes32 x, bytes32 y);
+ event TextChanged(bytes32 indexed node, string indexed indexedKey, string key);
+
+ struct PublicKey {
+ bytes32 x;
+ bytes32 y;
+ }
+
+ struct Record {
+ address addr;
+ bytes32 content;
+ string name;
+ PublicKey pubkey;
+ mapping(string=>string) text;
+ mapping(uint256=>bytes) abis;
+ }
+
+ AbstractENS ens;
+ mapping(bytes32=>Record) records;
+
+ modifier only_owner(bytes32 node) {
+ if (ens.owner(node) != msg.sender) throw;
+ _;
+ }
+
+ /**
+ * Constructor.
+ * @param ensAddr The ENS registrar contract.
+ */
+ function PublicResolver(AbstractENS ensAddr) {
+ ens = ensAddr;
+ }
+
+ /**
+ * Returns true if the resolver implements the interface specified by the provided hash.
+ * @param interfaceID The ID of the interface to check for.
+ * @return True if the contract implements the requested interface.
+ */
+ function supportsInterface(bytes4 interfaceID) constant returns (bool) {
+ return interfaceID == ADDR_INTERFACE_ID ||
+ interfaceID == CONTENT_INTERFACE_ID ||
+ interfaceID == NAME_INTERFACE_ID ||
+ interfaceID == ABI_INTERFACE_ID ||
+ interfaceID == PUBKEY_INTERFACE_ID ||
+ interfaceID == TEXT_INTERFACE_ID ||
+ interfaceID == INTERFACE_META_ID;
+ }
+
+ /**
+ * Returns the address associated with an ENS node.
+ * @param node The ENS node to query.
+ * @return The associated address.
+ */
+ function addr(bytes32 node) constant returns (address ret) {
+ ret = records[node].addr;
+ }
+
+ /**
+ * Sets the address associated with an ENS node.
+ * May only be called by the owner of that node in the ENS registry.
+ * @param node The node to update.
+ * @param addr The address to set.
+ */
+ function setAddr(bytes32 node, address addr) only_owner(node) {
+ records[node].addr = addr;
+ AddrChanged(node, addr);
+ }
+
+ /**
+ * Returns the content hash associated with an ENS node.
+ * Note that this resource type is not standardized, and will likely change
+ * in future to a resource type based on multihash.
+ * @param node The ENS node to query.
+ * @return The associated content hash.
+ */
+ function content(bytes32 node) constant returns (bytes32 ret) {
+ ret = records[node].content;
+ }
+
+ /**
+ * Sets the content hash associated with an ENS node.
+ * May only be called by the owner of that node in the ENS registry.
+ * Note that this resource type is not standardized, and will likely change
+ * in future to a resource type based on multihash.
+ * @param node The node to update.
+ * @param hash The content hash to set
+ */
+ function setContent(bytes32 node, bytes32 hash) only_owner(node) {
+ records[node].content = hash;
+ ContentChanged(node, hash);
+ }
+
+ /**
+ * Returns the name associated with an ENS node, for reverse records.
+ * Defined in EIP181.
+ * @param node The ENS node to query.
+ * @return The associated name.
+ */
+ function name(bytes32 node) constant returns (string ret) {
+ ret = records[node].name;
+ }
+
+ /**
+ * Sets the name associated with an ENS node, for reverse records.
+ * May only be called by the owner of that node in the ENS registry.
+ * @param node The node to update.
+ * @param name The name to set.
+ */
+ function setName(bytes32 node, string name) only_owner(node) {
+ records[node].name = name;
+ NameChanged(node, name);
+ }
+
+ /**
+ * Returns the ABI associated with an ENS node.
+ * Defined in EIP205.
+ * @param node The ENS node to query
+ * @param contentTypes A bitwise OR of the ABI formats accepted by the caller.
+ * @return contentType The content type of the return value
+ * @return data The ABI data
+ */
+ function ABI(bytes32 node, uint256 contentTypes) constant returns (uint256 contentType, bytes data) {
+ var record = records[node];
+ for(contentType = 1; contentType <= contentTypes; contentType <<= 1) {
+ if ((contentType & contentTypes) != 0 && record.abis[contentType].length > 0) {
+ data = record.abis[contentType];
+ return;
+ }
+ }
+ contentType = 0;
+ }
+
+ /**
+ * Sets the ABI associated with an ENS node.
+ * Nodes may have one ABI of each content type. To remove an ABI, set it to
+ * the empty string.
+ * @param node The node to update.
+ * @param contentType The content type of the ABI
+ * @param data The ABI data.
+ */
+ function setABI(bytes32 node, uint256 contentType, bytes data) only_owner(node) {
+ // Content types must be powers of 2
+ if (((contentType - 1) & contentType) != 0) throw;
+
+ records[node].abis[contentType] = data;
+ ABIChanged(node, contentType);
+ }
+
+ /**
+ * Returns the SECP256k1 public key associated with an ENS node.
+ * Defined in EIP 619.
+ * @param node The ENS node to query
+ * @return x, y the X and Y coordinates of the curve point for the public key.
+ */
+ function pubkey(bytes32 node) constant returns (bytes32 x, bytes32 y) {
+ return (records[node].pubkey.x, records[node].pubkey.y);
+ }
+
+ /**
+ * Sets the SECP256k1 public key associated with an ENS node.
+ * @param node The ENS node to query
+ * @param x the X coordinate of the curve point for the public key.
+ * @param y the Y coordinate of the curve point for the public key.
+ */
+ function setPubkey(bytes32 node, bytes32 x, bytes32 y) only_owner(node) {
+ records[node].pubkey = PublicKey(x, y);
+ PubkeyChanged(node, x, y);
+ }
+
+ /**
+ * Returns the text data associated with an ENS node and key.
+ * @param node The ENS node to query.
+ * @param key The text data key to query.
+ * @return The associated text data.
+ */
+ function text(bytes32 node, string key) constant returns (string ret) {
+ ret = records[node].text[key];
+ }
+
+ /**
+ * Sets the text data associated with an ENS node and key.
+ * May only be called by the owner of that node in the ENS registry.
+ * @param node The node to update.
+ * @param key The key to set.
+ * @param value The text data value to set.
+ */
+ function setText(bytes32 node, string key, string value) only_owner(node) {
+ records[node].text[key] = value;
+ TextChanged(node, key, key);
+ }
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/contracts/ens/fallback_contract/publicresolver.go b/vendor/github.com/ethereum/go-ethereum/contracts/ens/fallback_contract/publicresolver.go
new file mode 100644
index 00000000..a2a4be1c
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/contracts/ens/fallback_contract/publicresolver.go
@@ -0,0 +1,1321 @@
+// Code generated - DO NOT EDIT.
+// This file is a generated binding and any manual changes will be lost.
+
+package fallback_contract
+
+import (
+ "math/big"
+ "strings"
+
+ ethereum "github.com/ethereum/go-ethereum"
+ "github.com/ethereum/go-ethereum/accounts/abi"
+ "github.com/ethereum/go-ethereum/accounts/abi/bind"
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/core/types"
+ "github.com/ethereum/go-ethereum/event"
+)
+
+// PublicResolverABI is the input ABI used to generate the binding from.
+const PublicResolverABI = "[{\"constant\":true,\"inputs\":[{\"name\":\"interfaceID\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"},{\"name\":\"key\",\"type\":\"string\"},{\"name\":\"value\",\"type\":\"string\"}],\"name\":\"setText\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"},{\"name\":\"contentTypes\",\"type\":\"uint256\"}],\"name\":\"ABI\",\"outputs\":[{\"name\":\"contentType\",\"type\":\"uint256\"},{\"name\":\"data\",\"type\":\"bytes\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"},{\"name\":\"x\",\"type\":\"bytes32\"},{\"name\":\"y\",\"type\":\"bytes32\"}],\"name\":\"setPubkey\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"}],\"name\":\"content\",\"outputs\":[{\"name\":\"ret\",\"type\":\"bytes32\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"}],\"name\":\"addr\",\"outputs\":[{\"name\":\"ret\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"},{\"name\":\"key\",\"type\":\"string\"}],\"name\":\"text\",\"outputs\":[{\"name\":\"ret\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"},{\"name\":\"contentType\",\"type\":\"uint256\"},{\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"setABI\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"}],\"name\":\"name\",\"outputs\":[{\"name\":\"ret\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"},{\"name\":\"name\",\"type\":\"string\"}],\"name\":\"setName\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"},{\"name\":\"hash\",\"type\":\"bytes32\"}],\"name\":\"setContent\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"}],\"name\":\"pubkey\",\"outputs\":[{\"name\":\"x\",\"type\":\"bytes32\"},{\"name\":\"y\",\"type\":\"bytes32\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"node\",\"type\":\"bytes32\"},{\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"setAddr\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"name\":\"ensAddr\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"node\",\"type\":\"bytes32\"},{\"indexed\":false,\"name\":\"a\",\"type\":\"address\"}],\"name\":\"AddrChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"node\",\"type\":\"bytes32\"},{\"indexed\":false,\"name\":\"hash\",\"type\":\"bytes32\"}],\"name\":\"ContentChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"node\",\"type\":\"bytes32\"},{\"indexed\":false,\"name\":\"name\",\"type\":\"string\"}],\"name\":\"NameChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"node\",\"type\":\"bytes32\"},{\"indexed\":true,\"name\":\"contentType\",\"type\":\"uint256\"}],\"name\":\"ABIChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"node\",\"type\":\"bytes32\"},{\"indexed\":false,\"name\":\"x\",\"type\":\"bytes32\"},{\"indexed\":false,\"name\":\"y\",\"type\":\"bytes32\"}],\"name\":\"PubkeyChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"node\",\"type\":\"bytes32\"},{\"indexed\":true,\"name\":\"indexedKey\",\"type\":\"string\"},{\"indexed\":false,\"name\":\"key\",\"type\":\"string\"}],\"name\":\"TextChanged\",\"type\":\"event\"}]"
+
+// PublicResolverBin is the compiled bytecode used for deploying new contracts.
+const PublicResolverBin = `0x6060604052341561000f57600080fd5b6040516020806111b28339810160405280805160008054600160a060020a03909216600160a060020a0319909216919091179055505061115e806100546000396000f3006060604052600436106100ab5763ffffffff60e060020a60003504166301ffc9a781146100b057806310f13a8c146100e45780632203ab561461017e57806329cd62ea146102155780632dff6941146102315780633b3b57de1461025957806359d1d43c1461028b578063623195b014610358578063691f3431146103b457806377372213146103ca578063c3d014d614610420578063c869023314610439578063d5fa2b0014610467575b600080fd5b34156100bb57600080fd5b6100d0600160e060020a031960043516610489565b604051901515815260200160405180910390f35b34156100ef57600080fd5b61017c600480359060446024803590810190830135806020601f8201819004810201604051908101604052818152929190602084018383808284378201915050505050509190803590602001908201803590602001908080601f0160208091040260200160405190810160405281815292919060208401838380828437509496506105f695505050505050565b005b341561018957600080fd5b610197600435602435610807565b60405182815260406020820181815290820183818151815260200191508051906020019080838360005b838110156101d95780820151838201526020016101c1565b50505050905090810190601f1680156102065780820380516001836020036101000a031916815260200191505b50935050505060405180910390f35b341561022057600080fd5b61017c600435602435604435610931565b341561023c57600080fd5b610247600435610a30565b60405190815260200160405180910390f35b341561026457600080fd5b61026f600435610a46565b604051600160a060020a03909116815260200160405180910390f35b341561029657600080fd5b6102e1600480359060446024803590810190830135806020601f82018190048102016040519081016040528181529291906020840183838082843750949650610a6195505050505050565b60405160208082528190810183818151815260200191508051906020019080838360005b8381101561031d578082015183820152602001610305565b50505050905090810190601f16801561034a5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561036357600080fd5b61017c600480359060248035919060649060443590810190830135806020601f82018190048102016040519081016040528181529291906020840183838082843750949650610b8095505050505050565b34156103bf57600080fd5b6102e1600435610c7c565b34156103d557600080fd5b61017c600480359060446024803590810190830135806020601f82018190048102016040519081016040528181529291906020840183838082843750949650610d4295505050505050565b341561042b57600080fd5b61017c600435602435610e8c565b341561044457600080fd5b61044f600435610f65565b60405191825260208201526040908101905180910390f35b341561047257600080fd5b61017c600435600160a060020a0360243516610f82565b6000600160e060020a031982167f3b3b57de0000000000000000000000000000000000000000000000000000000014806104ec5750600160e060020a031982167fd8389dc500000000000000000000000000000000000000000000000000000000145b806105205750600160e060020a031982167f691f343100000000000000000000000000000000000000000000000000000000145b806105545750600160e060020a031982167f2203ab5600000000000000000000000000000000000000000000000000000000145b806105885750600160e060020a031982167fc869023300000000000000000000000000000000000000000000000000000000145b806105bc5750600160e060020a031982167f59d1d43c00000000000000000000000000000000000000000000000000000000145b806105f05750600160e060020a031982167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b600080548491600160a060020a033381169216906302571be39084906040516020015260405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b151561064f57600080fd5b6102c65a03f1151561066057600080fd5b50505060405180519050600160a060020a031614151561067f57600080fd5b6000848152600160205260409081902083916005909101908590518082805190602001908083835b602083106106c65780518252601f1990920191602091820191016106a7565b6001836020036101000a038019825116818451168082178552505050505050905001915050908152602001604051809103902090805161070a929160200190611085565b50826040518082805190602001908083835b6020831061073b5780518252601f19909201916020918201910161071c565b6001836020036101000a0380198251168184511617909252505050919091019250604091505051908190039020847fd8c9334b1a9c2f9da342a0a2b32629c1a229b6445dad78947f674b44444a75508560405160208082528190810183818151815260200191508051906020019080838360005b838110156107c75780820151838201526020016107af565b50505050905090810190601f1680156107f45780820380516001836020036101000a031916815260200191505b509250505060405180910390a350505050565b6000610811611103565b60008481526001602081905260409091209092505b838311610924578284161580159061085f5750600083815260068201602052604081205460026000196101006001841615020190911604115b15610919578060060160008481526020019081526020016000208054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561090d5780601f106108e25761010080835404028352916020019161090d565b820191906000526020600020905b8154815290600101906020018083116108f057829003601f168201915b50505050509150610929565b600290920291610826565b600092505b509250929050565b600080548491600160a060020a033381169216906302571be39084906040516020015260405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b151561098a57600080fd5b6102c65a03f1151561099b57600080fd5b50505060405180519050600160a060020a03161415156109ba57600080fd5b6040805190810160409081528482526020808301859052600087815260019091522060030181518155602082015160019091015550837f1d6f5e03d3f63eb58751986629a5439baee5079ff04f345becb66e23eb154e46848460405191825260208201526040908101905180910390a250505050565b6000908152600160208190526040909120015490565b600090815260016020526040902054600160a060020a031690565b610a69611103565b60008381526001602052604090819020600501908390518082805190602001908083835b60208310610aac5780518252601f199092019160209182019101610a8d565b6001836020036101000a03801982511681845116808217855250505050505090500191505090815260200160405180910390208054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610b735780601f10610b4857610100808354040283529160200191610b73565b820191906000526020600020905b815481529060010190602001808311610b5657829003601f168201915b5050505050905092915050565b600080548491600160a060020a033381169216906302571be39084906040516020015260405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515610bd957600080fd5b6102c65a03f11515610bea57600080fd5b50505060405180519050600160a060020a0316141515610c0957600080fd5b6000198301831615610c1a57600080fd5b60008481526001602090815260408083208684526006019091529020828051610c47929160200190611085565b5082847faa121bbeef5f32f5961a2a28966e769023910fc9479059ee3495d4c1a696efe360405160405180910390a350505050565b610c84611103565b6001600083600019166000191681526020019081526020016000206002018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610d365780601f10610d0b57610100808354040283529160200191610d36565b820191906000526020600020905b815481529060010190602001808311610d1957829003601f168201915b50505050509050919050565b600080548391600160a060020a033381169216906302571be39084906040516020015260405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515610d9b57600080fd5b6102c65a03f11515610dac57600080fd5b50505060405180519050600160a060020a0316141515610dcb57600080fd5b6000838152600160205260409020600201828051610ded929160200190611085565b50827fb7d29e911041e8d9b843369e890bcb72c9388692ba48b65ac54e7214c4c348f78360405160208082528190810183818151815260200191508051906020019080838360005b83811015610e4d578082015183820152602001610e35565b50505050905090810190601f168015610e7a5780820380516001836020036101000a031916815260200191505b509250505060405180910390a2505050565b600080548391600160a060020a033381169216906302571be39084906040516020015260405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515610ee557600080fd5b6102c65a03f11515610ef657600080fd5b50505060405180519050600160a060020a0316141515610f1557600080fd5b6000838152600160208190526040918290200183905583907f0424b6fe0d9c3bdbece0e7879dc241bb0c22e900be8b6c168b4ee08bd9bf83bc9084905190815260200160405180910390a2505050565b600090815260016020526040902060038101546004909101549091565b600080548391600160a060020a033381169216906302571be39084906040516020015260405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515610fdb57600080fd5b6102c65a03f11515610fec57600080fd5b50505060405180519050600160a060020a031614151561100b57600080fd5b60008381526001602052604090819020805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a03851617905583907f52d7d861f09ab3d26239d492e8968629f95e9e318cf0b73bfddc441522a15fd290849051600160a060020a03909116815260200160405180910390a2505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106110c657805160ff19168380011785556110f3565b828001600101855582156110f3579182015b828111156110f35782518255916020019190600101906110d8565b506110ff929150611115565b5090565b60206040519081016040526000815290565b61112f91905b808211156110ff576000815560010161111b565b905600a165627a7a723058201ecacbc445b9fbcd91b0ab164389f69d7283b856883bc7437eeed1008345a4920029`
+
+// DeployPublicResolver deploys a new Ethereum contract, binding an instance of PublicResolver to it.
+func DeployPublicResolver(auth *bind.TransactOpts, backend bind.ContractBackend, ensAddr common.Address) (common.Address, *types.Transaction, *PublicResolver, error) {
+ parsed, err := abi.JSON(strings.NewReader(PublicResolverABI))
+ if err != nil {
+ return common.Address{}, nil, nil, err
+ }
+ address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(PublicResolverBin), backend, ensAddr)
+ if err != nil {
+ return common.Address{}, nil, nil, err
+ }
+ return address, tx, &PublicResolver{PublicResolverCaller: PublicResolverCaller{contract: contract}, PublicResolverTransactor: PublicResolverTransactor{contract: contract}, PublicResolverFilterer: PublicResolverFilterer{contract: contract}}, nil
+}
+
+// PublicResolver is an auto generated Go binding around an Ethereum contract.
+type PublicResolver struct {
+ PublicResolverCaller // Read-only binding to the contract
+ PublicResolverTransactor // Write-only binding to the contract
+ PublicResolverFilterer // Log filterer for contract events
+}
+
+// PublicResolverCaller is an auto generated read-only Go binding around an Ethereum contract.
+type PublicResolverCaller struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// PublicResolverTransactor is an auto generated write-only Go binding around an Ethereum contract.
+type PublicResolverTransactor struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// PublicResolverFilterer is an auto generated log filtering Go binding around an Ethereum contract events.
+type PublicResolverFilterer struct {
+ contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// PublicResolverSession is an auto generated Go binding around an Ethereum contract,
+// with pre-set call and transact options.
+type PublicResolverSession struct {
+ Contract *PublicResolver // Generic contract binding to set the session for
+ CallOpts bind.CallOpts // Call options to use throughout this session
+ TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
+}
+
+// PublicResolverCallerSession is an auto generated read-only Go binding around an Ethereum contract,
+// with pre-set call options.
+type PublicResolverCallerSession struct {
+ Contract *PublicResolverCaller // Generic contract caller binding to set the session for
+ CallOpts bind.CallOpts // Call options to use throughout this session
+}
+
+// PublicResolverTransactorSession is an auto generated write-only Go binding around an Ethereum contract,
+// with pre-set transact options.
+type PublicResolverTransactorSession struct {
+ Contract *PublicResolverTransactor // Generic contract transactor binding to set the session for
+ TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
+}
+
+// PublicResolverRaw is an auto generated low-level Go binding around an Ethereum contract.
+type PublicResolverRaw struct {
+ Contract *PublicResolver // Generic contract binding to access the raw methods on
+}
+
+// PublicResolverCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract.
+type PublicResolverCallerRaw struct {
+ Contract *PublicResolverCaller // Generic read-only contract binding to access the raw methods on
+}
+
+// PublicResolverTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract.
+type PublicResolverTransactorRaw struct {
+ Contract *PublicResolverTransactor // Generic write-only contract binding to access the raw methods on
+}
+
+// NewPublicResolver creates a new instance of PublicResolver, bound to a specific deployed contract.
+func NewPublicResolver(address common.Address, backend bind.ContractBackend) (*PublicResolver, error) {
+ contract, err := bindPublicResolver(address, backend, backend, backend)
+ if err != nil {
+ return nil, err
+ }
+ return &PublicResolver{PublicResolverCaller: PublicResolverCaller{contract: contract}, PublicResolverTransactor: PublicResolverTransactor{contract: contract}, PublicResolverFilterer: PublicResolverFilterer{contract: contract}}, nil
+}
+
+// NewPublicResolverCaller creates a new read-only instance of PublicResolver, bound to a specific deployed contract.
+func NewPublicResolverCaller(address common.Address, caller bind.ContractCaller) (*PublicResolverCaller, error) {
+ contract, err := bindPublicResolver(address, caller, nil, nil)
+ if err != nil {
+ return nil, err
+ }
+ return &PublicResolverCaller{contract: contract}, nil
+}
+
+// NewPublicResolverTransactor creates a new write-only instance of PublicResolver, bound to a specific deployed contract.
+func NewPublicResolverTransactor(address common.Address, transactor bind.ContractTransactor) (*PublicResolverTransactor, error) {
+ contract, err := bindPublicResolver(address, nil, transactor, nil)
+ if err != nil {
+ return nil, err
+ }
+ return &PublicResolverTransactor{contract: contract}, nil
+}
+
+// NewPublicResolverFilterer creates a new log filterer instance of PublicResolver, bound to a specific deployed contract.
+func NewPublicResolverFilterer(address common.Address, filterer bind.ContractFilterer) (*PublicResolverFilterer, error) {
+ contract, err := bindPublicResolver(address, nil, nil, filterer)
+ if err != nil {
+ return nil, err
+ }
+ return &PublicResolverFilterer{contract: contract}, nil
+}
+
+// bindPublicResolver binds a generic wrapper to an already deployed contract.
+func bindPublicResolver(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) {
+ parsed, err := abi.JSON(strings.NewReader(PublicResolverABI))
+ if err != nil {
+ return nil, err
+ }
+ return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil
+}
+
+// Call invokes the (constant) contract method with params as input values and
+// sets the output to result. The result type might be a single field for simple
+// returns, a slice of interfaces for anonymous returns and a struct for named
+// returns.
+func (_PublicResolver *PublicResolverRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error {
+ return _PublicResolver.Contract.PublicResolverCaller.contract.Call(opts, result, method, params...)
+}
+
+// Transfer initiates a plain transaction to move funds to the contract, calling
+// its default method if one is available.
+func (_PublicResolver *PublicResolverRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _PublicResolver.Contract.PublicResolverTransactor.contract.Transfer(opts)
+}
+
+// Transact invokes the (paid) contract method with params as input values.
+func (_PublicResolver *PublicResolverRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+ return _PublicResolver.Contract.PublicResolverTransactor.contract.Transact(opts, method, params...)
+}
+
+// Call invokes the (constant) contract method with params as input values and
+// sets the output to result. The result type might be a single field for simple
+// returns, a slice of interfaces for anonymous returns and a struct for named
+// returns.
+func (_PublicResolver *PublicResolverCallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error {
+ return _PublicResolver.Contract.contract.Call(opts, result, method, params...)
+}
+
+// Transfer initiates a plain transaction to move funds to the contract, calling
+// its default method if one is available.
+func (_PublicResolver *PublicResolverTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _PublicResolver.Contract.contract.Transfer(opts)
+}
+
+// Transact invokes the (paid) contract method with params as input values.
+func (_PublicResolver *PublicResolverTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+ return _PublicResolver.Contract.contract.Transact(opts, method, params...)
+}
+
+// ABI is a free data retrieval call binding the contract method 0x2203ab56.
+//
+// Solidity: function ABI(node bytes32, contentTypes uint256) constant returns(contentType uint256, data bytes)
+func (_PublicResolver *PublicResolverCaller) ABI(opts *bind.CallOpts, node [32]byte, contentTypes *big.Int) (struct {
+ ContentType *big.Int
+ Data []byte
+}, error) {
+ ret := new(struct {
+ ContentType *big.Int
+ Data []byte
+ })
+ out := ret
+ err := _PublicResolver.contract.Call(opts, out, "ABI", node, contentTypes)
+ return *ret, err
+}
+
+// ABI is a free data retrieval call binding the contract method 0x2203ab56.
+//
+// Solidity: function ABI(node bytes32, contentTypes uint256) constant returns(contentType uint256, data bytes)
+func (_PublicResolver *PublicResolverSession) ABI(node [32]byte, contentTypes *big.Int) (struct {
+ ContentType *big.Int
+ Data []byte
+}, error) {
+ return _PublicResolver.Contract.ABI(&_PublicResolver.CallOpts, node, contentTypes)
+}
+
+// ABI is a free data retrieval call binding the contract method 0x2203ab56.
+//
+// Solidity: function ABI(node bytes32, contentTypes uint256) constant returns(contentType uint256, data bytes)
+func (_PublicResolver *PublicResolverCallerSession) ABI(node [32]byte, contentTypes *big.Int) (struct {
+ ContentType *big.Int
+ Data []byte
+}, error) {
+ return _PublicResolver.Contract.ABI(&_PublicResolver.CallOpts, node, contentTypes)
+}
+
+// Addr is a free data retrieval call binding the contract method 0x3b3b57de.
+//
+// Solidity: function addr(node bytes32) constant returns(ret address)
+func (_PublicResolver *PublicResolverCaller) Addr(opts *bind.CallOpts, node [32]byte) (common.Address, error) {
+ var (
+ ret0 = new(common.Address)
+ )
+ out := ret0
+ err := _PublicResolver.contract.Call(opts, out, "addr", node)
+ return *ret0, err
+}
+
+// Addr is a free data retrieval call binding the contract method 0x3b3b57de.
+//
+// Solidity: function addr(node bytes32) constant returns(ret address)
+func (_PublicResolver *PublicResolverSession) Addr(node [32]byte) (common.Address, error) {
+ return _PublicResolver.Contract.Addr(&_PublicResolver.CallOpts, node)
+}
+
+// Addr is a free data retrieval call binding the contract method 0x3b3b57de.
+//
+// Solidity: function addr(node bytes32) constant returns(ret address)
+func (_PublicResolver *PublicResolverCallerSession) Addr(node [32]byte) (common.Address, error) {
+ return _PublicResolver.Contract.Addr(&_PublicResolver.CallOpts, node)
+}
+
+// Content is a free data retrieval call binding the contract method 0x2dff6941.
+//
+// Solidity: function content(node bytes32) constant returns(ret bytes32)
+func (_PublicResolver *PublicResolverCaller) Content(opts *bind.CallOpts, node [32]byte) ([32]byte, error) {
+ var (
+ ret0 = new([32]byte)
+ )
+ out := ret0
+ err := _PublicResolver.contract.Call(opts, out, "content", node)
+ return *ret0, err
+}
+
+// Content is a free data retrieval call binding the contract method 0x2dff6941.
+//
+// Solidity: function content(node bytes32) constant returns(ret bytes32)
+func (_PublicResolver *PublicResolverSession) Content(node [32]byte) ([32]byte, error) {
+ return _PublicResolver.Contract.Content(&_PublicResolver.CallOpts, node)
+}
+
+// Content is a free data retrieval call binding the contract method 0x2dff6941.
+//
+// Solidity: function content(node bytes32) constant returns(ret bytes32)
+func (_PublicResolver *PublicResolverCallerSession) Content(node [32]byte) ([32]byte, error) {
+ return _PublicResolver.Contract.Content(&_PublicResolver.CallOpts, node)
+}
+
+// Name is a free data retrieval call binding the contract method 0x691f3431.
+//
+// Solidity: function name(node bytes32) constant returns(ret string)
+func (_PublicResolver *PublicResolverCaller) Name(opts *bind.CallOpts, node [32]byte) (string, error) {
+ var (
+ ret0 = new(string)
+ )
+ out := ret0
+ err := _PublicResolver.contract.Call(opts, out, "name", node)
+ return *ret0, err
+}
+
+// Name is a free data retrieval call binding the contract method 0x691f3431.
+//
+// Solidity: function name(node bytes32) constant returns(ret string)
+func (_PublicResolver *PublicResolverSession) Name(node [32]byte) (string, error) {
+ return _PublicResolver.Contract.Name(&_PublicResolver.CallOpts, node)
+}
+
+// Name is a free data retrieval call binding the contract method 0x691f3431.
+//
+// Solidity: function name(node bytes32) constant returns(ret string)
+func (_PublicResolver *PublicResolverCallerSession) Name(node [32]byte) (string, error) {
+ return _PublicResolver.Contract.Name(&_PublicResolver.CallOpts, node)
+}
+
+// Pubkey is a free data retrieval call binding the contract method 0xc8690233.
+//
+// Solidity: function pubkey(node bytes32) constant returns(x bytes32, y bytes32)
+func (_PublicResolver *PublicResolverCaller) Pubkey(opts *bind.CallOpts, node [32]byte) (struct {
+ X [32]byte
+ Y [32]byte
+}, error) {
+ ret := new(struct {
+ X [32]byte
+ Y [32]byte
+ })
+ out := ret
+ err := _PublicResolver.contract.Call(opts, out, "pubkey", node)
+ return *ret, err
+}
+
+// Pubkey is a free data retrieval call binding the contract method 0xc8690233.
+//
+// Solidity: function pubkey(node bytes32) constant returns(x bytes32, y bytes32)
+func (_PublicResolver *PublicResolverSession) Pubkey(node [32]byte) (struct {
+ X [32]byte
+ Y [32]byte
+}, error) {
+ return _PublicResolver.Contract.Pubkey(&_PublicResolver.CallOpts, node)
+}
+
+// Pubkey is a free data retrieval call binding the contract method 0xc8690233.
+//
+// Solidity: function pubkey(node bytes32) constant returns(x bytes32, y bytes32)
+func (_PublicResolver *PublicResolverCallerSession) Pubkey(node [32]byte) (struct {
+ X [32]byte
+ Y [32]byte
+}, error) {
+ return _PublicResolver.Contract.Pubkey(&_PublicResolver.CallOpts, node)
+}
+
+// SupportsInterface is a free data retrieval call binding the contract method 0x01ffc9a7.
+//
+// Solidity: function supportsInterface(interfaceID bytes4) constant returns(bool)
+func (_PublicResolver *PublicResolverCaller) SupportsInterface(opts *bind.CallOpts, interfaceID [4]byte) (bool, error) {
+ var (
+ ret0 = new(bool)
+ )
+ out := ret0
+ err := _PublicResolver.contract.Call(opts, out, "supportsInterface", interfaceID)
+ return *ret0, err
+}
+
+// SupportsInterface is a free data retrieval call binding the contract method 0x01ffc9a7.
+//
+// Solidity: function supportsInterface(interfaceID bytes4) constant returns(bool)
+func (_PublicResolver *PublicResolverSession) SupportsInterface(interfaceID [4]byte) (bool, error) {
+ return _PublicResolver.Contract.SupportsInterface(&_PublicResolver.CallOpts, interfaceID)
+}
+
+// SupportsInterface is a free data retrieval call binding the contract method 0x01ffc9a7.
+//
+// Solidity: function supportsInterface(interfaceID bytes4) constant returns(bool)
+func (_PublicResolver *PublicResolverCallerSession) SupportsInterface(interfaceID [4]byte) (bool, error) {
+ return _PublicResolver.Contract.SupportsInterface(&_PublicResolver.CallOpts, interfaceID)
+}
+
+// Text is a free data retrieval call binding the contract method 0x59d1d43c.
+//
+// Solidity: function text(node bytes32, key string) constant returns(ret string)
+func (_PublicResolver *PublicResolverCaller) Text(opts *bind.CallOpts, node [32]byte, key string) (string, error) {
+ var (
+ ret0 = new(string)
+ )
+ out := ret0
+ err := _PublicResolver.contract.Call(opts, out, "text", node, key)
+ return *ret0, err
+}
+
+// Text is a free data retrieval call binding the contract method 0x59d1d43c.
+//
+// Solidity: function text(node bytes32, key string) constant returns(ret string)
+func (_PublicResolver *PublicResolverSession) Text(node [32]byte, key string) (string, error) {
+ return _PublicResolver.Contract.Text(&_PublicResolver.CallOpts, node, key)
+}
+
+// Text is a free data retrieval call binding the contract method 0x59d1d43c.
+//
+// Solidity: function text(node bytes32, key string) constant returns(ret string)
+func (_PublicResolver *PublicResolverCallerSession) Text(node [32]byte, key string) (string, error) {
+ return _PublicResolver.Contract.Text(&_PublicResolver.CallOpts, node, key)
+}
+
+// SetABI is a paid mutator transaction binding the contract method 0x623195b0.
+//
+// Solidity: function setABI(node bytes32, contentType uint256, data bytes) returns()
+func (_PublicResolver *PublicResolverTransactor) SetABI(opts *bind.TransactOpts, node [32]byte, contentType *big.Int, data []byte) (*types.Transaction, error) {
+ return _PublicResolver.contract.Transact(opts, "setABI", node, contentType, data)
+}
+
+// SetABI is a paid mutator transaction binding the contract method 0x623195b0.
+//
+// Solidity: function setABI(node bytes32, contentType uint256, data bytes) returns()
+func (_PublicResolver *PublicResolverSession) SetABI(node [32]byte, contentType *big.Int, data []byte) (*types.Transaction, error) {
+ return _PublicResolver.Contract.SetABI(&_PublicResolver.TransactOpts, node, contentType, data)
+}
+
+// SetABI is a paid mutator transaction binding the contract method 0x623195b0.
+//
+// Solidity: function setABI(node bytes32, contentType uint256, data bytes) returns()
+func (_PublicResolver *PublicResolverTransactorSession) SetABI(node [32]byte, contentType *big.Int, data []byte) (*types.Transaction, error) {
+ return _PublicResolver.Contract.SetABI(&_PublicResolver.TransactOpts, node, contentType, data)
+}
+
+// SetAddr is a paid mutator transaction binding the contract method 0xd5fa2b00.
+//
+// Solidity: function setAddr(node bytes32, addr address) returns()
+func (_PublicResolver *PublicResolverTransactor) SetAddr(opts *bind.TransactOpts, node [32]byte, addr common.Address) (*types.Transaction, error) {
+ return _PublicResolver.contract.Transact(opts, "setAddr", node, addr)
+}
+
+// SetAddr is a paid mutator transaction binding the contract method 0xd5fa2b00.
+//
+// Solidity: function setAddr(node bytes32, addr address) returns()
+func (_PublicResolver *PublicResolverSession) SetAddr(node [32]byte, addr common.Address) (*types.Transaction, error) {
+ return _PublicResolver.Contract.SetAddr(&_PublicResolver.TransactOpts, node, addr)
+}
+
+// SetAddr is a paid mutator transaction binding the contract method 0xd5fa2b00.
+//
+// Solidity: function setAddr(node bytes32, addr address) returns()
+func (_PublicResolver *PublicResolverTransactorSession) SetAddr(node [32]byte, addr common.Address) (*types.Transaction, error) {
+ return _PublicResolver.Contract.SetAddr(&_PublicResolver.TransactOpts, node, addr)
+}
+
+// SetContent is a paid mutator transaction binding the contract method 0xc3d014d6.
+//
+// Solidity: function setContent(node bytes32, hash bytes32) returns()
+func (_PublicResolver *PublicResolverTransactor) SetContent(opts *bind.TransactOpts, node [32]byte, hash [32]byte) (*types.Transaction, error) {
+ return _PublicResolver.contract.Transact(opts, "setContent", node, hash)
+}
+
+// SetContent is a paid mutator transaction binding the contract method 0xc3d014d6.
+//
+// Solidity: function setContent(node bytes32, hash bytes32) returns()
+func (_PublicResolver *PublicResolverSession) SetContent(node [32]byte, hash [32]byte) (*types.Transaction, error) {
+ return _PublicResolver.Contract.SetContent(&_PublicResolver.TransactOpts, node, hash)
+}
+
+// SetContent is a paid mutator transaction binding the contract method 0xc3d014d6.
+//
+// Solidity: function setContent(node bytes32, hash bytes32) returns()
+func (_PublicResolver *PublicResolverTransactorSession) SetContent(node [32]byte, hash [32]byte) (*types.Transaction, error) {
+ return _PublicResolver.Contract.SetContent(&_PublicResolver.TransactOpts, node, hash)
+}
+
+// SetName is a paid mutator transaction binding the contract method 0x77372213.
+//
+// Solidity: function setName(node bytes32, name string) returns()
+func (_PublicResolver *PublicResolverTransactor) SetName(opts *bind.TransactOpts, node [32]byte, name string) (*types.Transaction, error) {
+ return _PublicResolver.contract.Transact(opts, "setName", node, name)
+}
+
+// SetName is a paid mutator transaction binding the contract method 0x77372213.
+//
+// Solidity: function setName(node bytes32, name string) returns()
+func (_PublicResolver *PublicResolverSession) SetName(node [32]byte, name string) (*types.Transaction, error) {
+ return _PublicResolver.Contract.SetName(&_PublicResolver.TransactOpts, node, name)
+}
+
+// SetName is a paid mutator transaction binding the contract method 0x77372213.
+//
+// Solidity: function setName(node bytes32, name string) returns()
+func (_PublicResolver *PublicResolverTransactorSession) SetName(node [32]byte, name string) (*types.Transaction, error) {
+ return _PublicResolver.Contract.SetName(&_PublicResolver.TransactOpts, node, name)
+}
+
+// SetPubkey is a paid mutator transaction binding the contract method 0x29cd62ea.
+//
+// Solidity: function setPubkey(node bytes32, x bytes32, y bytes32) returns()
+func (_PublicResolver *PublicResolverTransactor) SetPubkey(opts *bind.TransactOpts, node [32]byte, x [32]byte, y [32]byte) (*types.Transaction, error) {
+ return _PublicResolver.contract.Transact(opts, "setPubkey", node, x, y)
+}
+
+// SetPubkey is a paid mutator transaction binding the contract method 0x29cd62ea.
+//
+// Solidity: function setPubkey(node bytes32, x bytes32, y bytes32) returns()
+func (_PublicResolver *PublicResolverSession) SetPubkey(node [32]byte, x [32]byte, y [32]byte) (*types.Transaction, error) {
+ return _PublicResolver.Contract.SetPubkey(&_PublicResolver.TransactOpts, node, x, y)
+}
+
+// SetPubkey is a paid mutator transaction binding the contract method 0x29cd62ea.
+//
+// Solidity: function setPubkey(node bytes32, x bytes32, y bytes32) returns()
+func (_PublicResolver *PublicResolverTransactorSession) SetPubkey(node [32]byte, x [32]byte, y [32]byte) (*types.Transaction, error) {
+ return _PublicResolver.Contract.SetPubkey(&_PublicResolver.TransactOpts, node, x, y)
+}
+
+// SetText is a paid mutator transaction binding the contract method 0x10f13a8c.
+//
+// Solidity: function setText(node bytes32, key string, value string) returns()
+func (_PublicResolver *PublicResolverTransactor) SetText(opts *bind.TransactOpts, node [32]byte, key string, value string) (*types.Transaction, error) {
+ return _PublicResolver.contract.Transact(opts, "setText", node, key, value)
+}
+
+// SetText is a paid mutator transaction binding the contract method 0x10f13a8c.
+//
+// Solidity: function setText(node bytes32, key string, value string) returns()
+func (_PublicResolver *PublicResolverSession) SetText(node [32]byte, key string, value string) (*types.Transaction, error) {
+ return _PublicResolver.Contract.SetText(&_PublicResolver.TransactOpts, node, key, value)
+}
+
+// SetText is a paid mutator transaction binding the contract method 0x10f13a8c.
+//
+// Solidity: function setText(node bytes32, key string, value string) returns()
+func (_PublicResolver *PublicResolverTransactorSession) SetText(node [32]byte, key string, value string) (*types.Transaction, error) {
+ return _PublicResolver.Contract.SetText(&_PublicResolver.TransactOpts, node, key, value)
+}
+
+// PublicResolverABIChangedIterator is returned from FilterABIChanged and is used to iterate over the raw logs and unpacked data for ABIChanged events raised by the PublicResolver contract.
+type PublicResolverABIChangedIterator struct {
+ Event *PublicResolverABIChanged // Event containing the contract specifics and raw log
+
+ contract *bind.BoundContract // Generic contract to use for unpacking event data
+ event string // Event name to use for unpacking event data
+
+ logs chan types.Log // Log channel receiving the found contract events
+ sub ethereum.Subscription // Subscription for errors, completion and termination
+ done bool // Whether the subscription completed delivering logs
+ fail error // Occurred error to stop iteration
+}
+
+// Next advances the iterator to the subsequent event, returning whether there
+// are any more events found. In case of a retrieval or parsing error, false is
+// returned and Error() can be queried for the exact failure.
+func (it *PublicResolverABIChangedIterator) Next() bool {
+ // If the iterator failed, stop iterating
+ if it.fail != nil {
+ return false
+ }
+ // If the iterator completed, deliver directly whatever's available
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(PublicResolverABIChanged)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+ // Iterator still in progress, wait for either a data or an error event
+ select {
+ case log := <-it.logs:
+ it.Event = new(PublicResolverABIChanged)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+// Error retruned any retrieval or parsing error occurred during filtering.
+func (it *PublicResolverABIChangedIterator) Error() error {
+ return it.fail
+}
+
+// Close terminates the iteration process, releasing any pending underlying
+// resources.
+func (it *PublicResolverABIChangedIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+// PublicResolverABIChanged represents a ABIChanged event raised by the PublicResolver contract.
+type PublicResolverABIChanged struct {
+ Node [32]byte
+ ContentType *big.Int
+ Raw types.Log // Blockchain specific contextual infos
+}
+
+// FilterABIChanged is a free log retrieval operation binding the contract event 0xaa121bbeef5f32f5961a2a28966e769023910fc9479059ee3495d4c1a696efe3.
+//
+// Solidity: event ABIChanged(node indexed bytes32, contentType indexed uint256)
+func (_PublicResolver *PublicResolverFilterer) FilterABIChanged(opts *bind.FilterOpts, node [][32]byte, contentType []*big.Int) (*PublicResolverABIChangedIterator, error) {
+
+ var nodeRule []interface{}
+ for _, nodeItem := range node {
+ nodeRule = append(nodeRule, nodeItem)
+ }
+ var contentTypeRule []interface{}
+ for _, contentTypeItem := range contentType {
+ contentTypeRule = append(contentTypeRule, contentTypeItem)
+ }
+
+ logs, sub, err := _PublicResolver.contract.FilterLogs(opts, "ABIChanged", nodeRule, contentTypeRule)
+ if err != nil {
+ return nil, err
+ }
+ return &PublicResolverABIChangedIterator{contract: _PublicResolver.contract, event: "ABIChanged", logs: logs, sub: sub}, nil
+}
+
+// WatchABIChanged is a free log subscription operation binding the contract event 0xaa121bbeef5f32f5961a2a28966e769023910fc9479059ee3495d4c1a696efe3.
+//
+// Solidity: event ABIChanged(node indexed bytes32, contentType indexed uint256)
+func (_PublicResolver *PublicResolverFilterer) WatchABIChanged(opts *bind.WatchOpts, sink chan<- *PublicResolverABIChanged, node [][32]byte, contentType []*big.Int) (event.Subscription, error) {
+
+ var nodeRule []interface{}
+ for _, nodeItem := range node {
+ nodeRule = append(nodeRule, nodeItem)
+ }
+ var contentTypeRule []interface{}
+ for _, contentTypeItem := range contentType {
+ contentTypeRule = append(contentTypeRule, contentTypeItem)
+ }
+
+ logs, sub, err := _PublicResolver.contract.WatchLogs(opts, "ABIChanged", nodeRule, contentTypeRule)
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+ // New log arrived, parse the event and forward to the user
+ event := new(PublicResolverABIChanged)
+ if err := _PublicResolver.contract.UnpackLog(event, "ABIChanged", log); err != nil {
+ return err
+ }
+ event.Raw = log
+
+ select {
+ case sink <- event:
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ }
+ }), nil
+}
+
+// PublicResolverAddrChangedIterator is returned from FilterAddrChanged and is used to iterate over the raw logs and unpacked data for AddrChanged events raised by the PublicResolver contract.
+type PublicResolverAddrChangedIterator struct {
+ Event *PublicResolverAddrChanged // Event containing the contract specifics and raw log
+
+ contract *bind.BoundContract // Generic contract to use for unpacking event data
+ event string // Event name to use for unpacking event data
+
+ logs chan types.Log // Log channel receiving the found contract events
+ sub ethereum.Subscription // Subscription for errors, completion and termination
+ done bool // Whether the subscription completed delivering logs
+ fail error // Occurred error to stop iteration
+}
+
+// Next advances the iterator to the subsequent event, returning whether there
+// are any more events found. In case of a retrieval or parsing error, false is
+// returned and Error() can be queried for the exact failure.
+func (it *PublicResolverAddrChangedIterator) Next() bool {
+ // If the iterator failed, stop iterating
+ if it.fail != nil {
+ return false
+ }
+ // If the iterator completed, deliver directly whatever's available
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(PublicResolverAddrChanged)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+ // Iterator still in progress, wait for either a data or an error event
+ select {
+ case log := <-it.logs:
+ it.Event = new(PublicResolverAddrChanged)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+// Error retruned any retrieval or parsing error occurred during filtering.
+func (it *PublicResolverAddrChangedIterator) Error() error {
+ return it.fail
+}
+
+// Close terminates the iteration process, releasing any pending underlying
+// resources.
+func (it *PublicResolverAddrChangedIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+// PublicResolverAddrChanged represents a AddrChanged event raised by the PublicResolver contract.
+type PublicResolverAddrChanged struct {
+ Node [32]byte
+ A common.Address
+ Raw types.Log // Blockchain specific contextual infos
+}
+
+// FilterAddrChanged is a free log retrieval operation binding the contract event 0x52d7d861f09ab3d26239d492e8968629f95e9e318cf0b73bfddc441522a15fd2.
+//
+// Solidity: event AddrChanged(node indexed bytes32, a address)
+func (_PublicResolver *PublicResolverFilterer) FilterAddrChanged(opts *bind.FilterOpts, node [][32]byte) (*PublicResolverAddrChangedIterator, error) {
+
+ var nodeRule []interface{}
+ for _, nodeItem := range node {
+ nodeRule = append(nodeRule, nodeItem)
+ }
+
+ logs, sub, err := _PublicResolver.contract.FilterLogs(opts, "AddrChanged", nodeRule)
+ if err != nil {
+ return nil, err
+ }
+ return &PublicResolverAddrChangedIterator{contract: _PublicResolver.contract, event: "AddrChanged", logs: logs, sub: sub}, nil
+}
+
+// WatchAddrChanged is a free log subscription operation binding the contract event 0x52d7d861f09ab3d26239d492e8968629f95e9e318cf0b73bfddc441522a15fd2.
+//
+// Solidity: event AddrChanged(node indexed bytes32, a address)
+func (_PublicResolver *PublicResolverFilterer) WatchAddrChanged(opts *bind.WatchOpts, sink chan<- *PublicResolverAddrChanged, node [][32]byte) (event.Subscription, error) {
+
+ var nodeRule []interface{}
+ for _, nodeItem := range node {
+ nodeRule = append(nodeRule, nodeItem)
+ }
+
+ logs, sub, err := _PublicResolver.contract.WatchLogs(opts, "AddrChanged", nodeRule)
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+ // New log arrived, parse the event and forward to the user
+ event := new(PublicResolverAddrChanged)
+ if err := _PublicResolver.contract.UnpackLog(event, "AddrChanged", log); err != nil {
+ return err
+ }
+ event.Raw = log
+
+ select {
+ case sink <- event:
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ }
+ }), nil
+}
+
+// PublicResolverContentChangedIterator is returned from FilterContentChanged and is used to iterate over the raw logs and unpacked data for ContentChanged events raised by the PublicResolver contract.
+type PublicResolverContentChangedIterator struct {
+ Event *PublicResolverContentChanged // Event containing the contract specifics and raw log
+
+ contract *bind.BoundContract // Generic contract to use for unpacking event data
+ event string // Event name to use for unpacking event data
+
+ logs chan types.Log // Log channel receiving the found contract events
+ sub ethereum.Subscription // Subscription for errors, completion and termination
+ done bool // Whether the subscription completed delivering logs
+ fail error // Occurred error to stop iteration
+}
+
+// Next advances the iterator to the subsequent event, returning whether there
+// are any more events found. In case of a retrieval or parsing error, false is
+// returned and Error() can be queried for the exact failure.
+func (it *PublicResolverContentChangedIterator) Next() bool {
+ // If the iterator failed, stop iterating
+ if it.fail != nil {
+ return false
+ }
+ // If the iterator completed, deliver directly whatever's available
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(PublicResolverContentChanged)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+ // Iterator still in progress, wait for either a data or an error event
+ select {
+ case log := <-it.logs:
+ it.Event = new(PublicResolverContentChanged)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+// Error retruned any retrieval or parsing error occurred during filtering.
+func (it *PublicResolverContentChangedIterator) Error() error {
+ return it.fail
+}
+
+// Close terminates the iteration process, releasing any pending underlying
+// resources.
+func (it *PublicResolverContentChangedIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+// PublicResolverContentChanged represents a ContentChanged event raised by the PublicResolver contract.
+type PublicResolverContentChanged struct {
+ Node [32]byte
+ Hash [32]byte
+ Raw types.Log // Blockchain specific contextual infos
+}
+
+// FilterContentChanged is a free log retrieval operation binding the contract event 0x0424b6fe0d9c3bdbece0e7879dc241bb0c22e900be8b6c168b4ee08bd9bf83bc.
+//
+// Solidity: event ContentChanged(node indexed bytes32, hash bytes32)
+func (_PublicResolver *PublicResolverFilterer) FilterContentChanged(opts *bind.FilterOpts, node [][32]byte) (*PublicResolverContentChangedIterator, error) {
+
+ var nodeRule []interface{}
+ for _, nodeItem := range node {
+ nodeRule = append(nodeRule, nodeItem)
+ }
+
+ logs, sub, err := _PublicResolver.contract.FilterLogs(opts, "ContentChanged", nodeRule)
+ if err != nil {
+ return nil, err
+ }
+ return &PublicResolverContentChangedIterator{contract: _PublicResolver.contract, event: "ContentChanged", logs: logs, sub: sub}, nil
+}
+
+// WatchContentChanged is a free log subscription operation binding the contract event 0x0424b6fe0d9c3bdbece0e7879dc241bb0c22e900be8b6c168b4ee08bd9bf83bc.
+//
+// Solidity: event ContentChanged(node indexed bytes32, hash bytes32)
+func (_PublicResolver *PublicResolverFilterer) WatchContentChanged(opts *bind.WatchOpts, sink chan<- *PublicResolverContentChanged, node [][32]byte) (event.Subscription, error) {
+
+ var nodeRule []interface{}
+ for _, nodeItem := range node {
+ nodeRule = append(nodeRule, nodeItem)
+ }
+
+ logs, sub, err := _PublicResolver.contract.WatchLogs(opts, "ContentChanged", nodeRule)
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+ // New log arrived, parse the event and forward to the user
+ event := new(PublicResolverContentChanged)
+ if err := _PublicResolver.contract.UnpackLog(event, "ContentChanged", log); err != nil {
+ return err
+ }
+ event.Raw = log
+
+ select {
+ case sink <- event:
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ }
+ }), nil
+}
+
+// PublicResolverNameChangedIterator is returned from FilterNameChanged and is used to iterate over the raw logs and unpacked data for NameChanged events raised by the PublicResolver contract.
+type PublicResolverNameChangedIterator struct {
+ Event *PublicResolverNameChanged // Event containing the contract specifics and raw log
+
+ contract *bind.BoundContract // Generic contract to use for unpacking event data
+ event string // Event name to use for unpacking event data
+
+ logs chan types.Log // Log channel receiving the found contract events
+ sub ethereum.Subscription // Subscription for errors, completion and termination
+ done bool // Whether the subscription completed delivering logs
+ fail error // Occurred error to stop iteration
+}
+
+// Next advances the iterator to the subsequent event, returning whether there
+// are any more events found. In case of a retrieval or parsing error, false is
+// returned and Error() can be queried for the exact failure.
+func (it *PublicResolverNameChangedIterator) Next() bool {
+ // If the iterator failed, stop iterating
+ if it.fail != nil {
+ return false
+ }
+ // If the iterator completed, deliver directly whatever's available
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(PublicResolverNameChanged)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+ // Iterator still in progress, wait for either a data or an error event
+ select {
+ case log := <-it.logs:
+ it.Event = new(PublicResolverNameChanged)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+// Error retruned any retrieval or parsing error occurred during filtering.
+func (it *PublicResolverNameChangedIterator) Error() error {
+ return it.fail
+}
+
+// Close terminates the iteration process, releasing any pending underlying
+// resources.
+func (it *PublicResolverNameChangedIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+// PublicResolverNameChanged represents a NameChanged event raised by the PublicResolver contract.
+type PublicResolverNameChanged struct {
+ Node [32]byte
+ Name string
+ Raw types.Log // Blockchain specific contextual infos
+}
+
+// FilterNameChanged is a free log retrieval operation binding the contract event 0xb7d29e911041e8d9b843369e890bcb72c9388692ba48b65ac54e7214c4c348f7.
+//
+// Solidity: event NameChanged(node indexed bytes32, name string)
+func (_PublicResolver *PublicResolverFilterer) FilterNameChanged(opts *bind.FilterOpts, node [][32]byte) (*PublicResolverNameChangedIterator, error) {
+
+ var nodeRule []interface{}
+ for _, nodeItem := range node {
+ nodeRule = append(nodeRule, nodeItem)
+ }
+
+ logs, sub, err := _PublicResolver.contract.FilterLogs(opts, "NameChanged", nodeRule)
+ if err != nil {
+ return nil, err
+ }
+ return &PublicResolverNameChangedIterator{contract: _PublicResolver.contract, event: "NameChanged", logs: logs, sub: sub}, nil
+}
+
+// WatchNameChanged is a free log subscription operation binding the contract event 0xb7d29e911041e8d9b843369e890bcb72c9388692ba48b65ac54e7214c4c348f7.
+//
+// Solidity: event NameChanged(node indexed bytes32, name string)
+func (_PublicResolver *PublicResolverFilterer) WatchNameChanged(opts *bind.WatchOpts, sink chan<- *PublicResolverNameChanged, node [][32]byte) (event.Subscription, error) {
+
+ var nodeRule []interface{}
+ for _, nodeItem := range node {
+ nodeRule = append(nodeRule, nodeItem)
+ }
+
+ logs, sub, err := _PublicResolver.contract.WatchLogs(opts, "NameChanged", nodeRule)
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+ // New log arrived, parse the event and forward to the user
+ event := new(PublicResolverNameChanged)
+ if err := _PublicResolver.contract.UnpackLog(event, "NameChanged", log); err != nil {
+ return err
+ }
+ event.Raw = log
+
+ select {
+ case sink <- event:
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ }
+ }), nil
+}
+
+// PublicResolverPubkeyChangedIterator is returned from FilterPubkeyChanged and is used to iterate over the raw logs and unpacked data for PubkeyChanged events raised by the PublicResolver contract.
+type PublicResolverPubkeyChangedIterator struct {
+ Event *PublicResolverPubkeyChanged // Event containing the contract specifics and raw log
+
+ contract *bind.BoundContract // Generic contract to use for unpacking event data
+ event string // Event name to use for unpacking event data
+
+ logs chan types.Log // Log channel receiving the found contract events
+ sub ethereum.Subscription // Subscription for errors, completion and termination
+ done bool // Whether the subscription completed delivering logs
+ fail error // Occurred error to stop iteration
+}
+
+// Next advances the iterator to the subsequent event, returning whether there
+// are any more events found. In case of a retrieval or parsing error, false is
+// returned and Error() can be queried for the exact failure.
+func (it *PublicResolverPubkeyChangedIterator) Next() bool {
+ // If the iterator failed, stop iterating
+ if it.fail != nil {
+ return false
+ }
+ // If the iterator completed, deliver directly whatever's available
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(PublicResolverPubkeyChanged)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+ // Iterator still in progress, wait for either a data or an error event
+ select {
+ case log := <-it.logs:
+ it.Event = new(PublicResolverPubkeyChanged)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+// Error retruned any retrieval or parsing error occurred during filtering.
+func (it *PublicResolverPubkeyChangedIterator) Error() error {
+ return it.fail
+}
+
+// Close terminates the iteration process, releasing any pending underlying
+// resources.
+func (it *PublicResolverPubkeyChangedIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+// PublicResolverPubkeyChanged represents a PubkeyChanged event raised by the PublicResolver contract.
+type PublicResolverPubkeyChanged struct {
+ Node [32]byte
+ X [32]byte
+ Y [32]byte
+ Raw types.Log // Blockchain specific contextual infos
+}
+
+// FilterPubkeyChanged is a free log retrieval operation binding the contract event 0x1d6f5e03d3f63eb58751986629a5439baee5079ff04f345becb66e23eb154e46.
+//
+// Solidity: event PubkeyChanged(node indexed bytes32, x bytes32, y bytes32)
+func (_PublicResolver *PublicResolverFilterer) FilterPubkeyChanged(opts *bind.FilterOpts, node [][32]byte) (*PublicResolverPubkeyChangedIterator, error) {
+
+ var nodeRule []interface{}
+ for _, nodeItem := range node {
+ nodeRule = append(nodeRule, nodeItem)
+ }
+
+ logs, sub, err := _PublicResolver.contract.FilterLogs(opts, "PubkeyChanged", nodeRule)
+ if err != nil {
+ return nil, err
+ }
+ return &PublicResolverPubkeyChangedIterator{contract: _PublicResolver.contract, event: "PubkeyChanged", logs: logs, sub: sub}, nil
+}
+
+// WatchPubkeyChanged is a free log subscription operation binding the contract event 0x1d6f5e03d3f63eb58751986629a5439baee5079ff04f345becb66e23eb154e46.
+//
+// Solidity: event PubkeyChanged(node indexed bytes32, x bytes32, y bytes32)
+func (_PublicResolver *PublicResolverFilterer) WatchPubkeyChanged(opts *bind.WatchOpts, sink chan<- *PublicResolverPubkeyChanged, node [][32]byte) (event.Subscription, error) {
+
+ var nodeRule []interface{}
+ for _, nodeItem := range node {
+ nodeRule = append(nodeRule, nodeItem)
+ }
+
+ logs, sub, err := _PublicResolver.contract.WatchLogs(opts, "PubkeyChanged", nodeRule)
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+ // New log arrived, parse the event and forward to the user
+ event := new(PublicResolverPubkeyChanged)
+ if err := _PublicResolver.contract.UnpackLog(event, "PubkeyChanged", log); err != nil {
+ return err
+ }
+ event.Raw = log
+
+ select {
+ case sink <- event:
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ }
+ }), nil
+}
+
+// PublicResolverTextChangedIterator is returned from FilterTextChanged and is used to iterate over the raw logs and unpacked data for TextChanged events raised by the PublicResolver contract.
+type PublicResolverTextChangedIterator struct {
+ Event *PublicResolverTextChanged // Event containing the contract specifics and raw log
+
+ contract *bind.BoundContract // Generic contract to use for unpacking event data
+ event string // Event name to use for unpacking event data
+
+ logs chan types.Log // Log channel receiving the found contract events
+ sub ethereum.Subscription // Subscription for errors, completion and termination
+ done bool // Whether the subscription completed delivering logs
+ fail error // Occurred error to stop iteration
+}
+
+// Next advances the iterator to the subsequent event, returning whether there
+// are any more events found. In case of a retrieval or parsing error, false is
+// returned and Error() can be queried for the exact failure.
+func (it *PublicResolverTextChangedIterator) Next() bool {
+ // If the iterator failed, stop iterating
+ if it.fail != nil {
+ return false
+ }
+ // If the iterator completed, deliver directly whatever's available
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(PublicResolverTextChanged)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+ // Iterator still in progress, wait for either a data or an error event
+ select {
+ case log := <-it.logs:
+ it.Event = new(PublicResolverTextChanged)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+// Error retruned any retrieval or parsing error occurred during filtering.
+func (it *PublicResolverTextChangedIterator) Error() error {
+ return it.fail
+}
+
+// Close terminates the iteration process, releasing any pending underlying
+// resources.
+func (it *PublicResolverTextChangedIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+// PublicResolverTextChanged represents a TextChanged event raised by the PublicResolver contract.
+type PublicResolverTextChanged struct {
+ Node [32]byte
+ IndexedKey common.Hash
+ Key string
+ Raw types.Log // Blockchain specific contextual infos
+}
+
+// FilterTextChanged is a free log retrieval operation binding the contract event 0xd8c9334b1a9c2f9da342a0a2b32629c1a229b6445dad78947f674b44444a7550.
+//
+// Solidity: event TextChanged(node indexed bytes32, indexedKey indexed string, key string)
+func (_PublicResolver *PublicResolverFilterer) FilterTextChanged(opts *bind.FilterOpts, node [][32]byte, indexedKey []string) (*PublicResolverTextChangedIterator, error) {
+
+ var nodeRule []interface{}
+ for _, nodeItem := range node {
+ nodeRule = append(nodeRule, nodeItem)
+ }
+ var indexedKeyRule []interface{}
+ for _, indexedKeyItem := range indexedKey {
+ indexedKeyRule = append(indexedKeyRule, indexedKeyItem)
+ }
+
+ logs, sub, err := _PublicResolver.contract.FilterLogs(opts, "TextChanged", nodeRule, indexedKeyRule)
+ if err != nil {
+ return nil, err
+ }
+ return &PublicResolverTextChangedIterator{contract: _PublicResolver.contract, event: "TextChanged", logs: logs, sub: sub}, nil
+}
+
+// WatchTextChanged is a free log subscription operation binding the contract event 0xd8c9334b1a9c2f9da342a0a2b32629c1a229b6445dad78947f674b44444a7550.
+//
+// Solidity: event TextChanged(node indexed bytes32, indexedKey indexed string, key string)
+func (_PublicResolver *PublicResolverFilterer) WatchTextChanged(opts *bind.WatchOpts, sink chan<- *PublicResolverTextChanged, node [][32]byte, indexedKey []string) (event.Subscription, error) {
+
+ var nodeRule []interface{}
+ for _, nodeItem := range node {
+ nodeRule = append(nodeRule, nodeItem)
+ }
+ var indexedKeyRule []interface{}
+ for _, indexedKeyItem := range indexedKey {
+ indexedKeyRule = append(indexedKeyRule, indexedKeyItem)
+ }
+
+ logs, sub, err := _PublicResolver.contract.WatchLogs(opts, "TextChanged", nodeRule, indexedKeyRule)
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+ // New log arrived, parse the event and forward to the user
+ event := new(PublicResolverTextChanged)
+ if err := _PublicResolver.contract.UnpackLog(event, "TextChanged", log); err != nil {
+ return err
+ }
+ event.Raw = log
+
+ select {
+ case sink <- event:
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ }
+ }), nil
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/core/asm/asm.go b/vendor/github.com/ethereum/go-ethereum/core/asm/asm.go
new file mode 100644
index 00000000..4257198c
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/core/asm/asm.go
@@ -0,0 +1,136 @@
+// Copyright 2017 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+// Provides support for dealing with EVM assembly instructions (e.g., disassembling them).
+package asm
+
+import (
+ "encoding/hex"
+ "fmt"
+
+ "github.com/ethereum/go-ethereum/core/vm"
+)
+
+// Iterator for disassembled EVM instructions
+type instructionIterator struct {
+ code []byte
+ pc uint64
+ arg []byte
+ op vm.OpCode
+ error error
+ started bool
+}
+
+// Create a new instruction iterator.
+func NewInstructionIterator(code []byte) *instructionIterator {
+ it := new(instructionIterator)
+ it.code = code
+ return it
+}
+
+// Returns true if there is a next instruction and moves on.
+func (it *instructionIterator) Next() bool {
+ if it.error != nil || uint64(len(it.code)) <= it.pc {
+ // We previously reached an error or the end.
+ return false
+ }
+
+ if it.started {
+ // Since the iteration has been already started we move to the next instruction.
+ if it.arg != nil {
+ it.pc += uint64(len(it.arg))
+ }
+ it.pc++
+ } else {
+ // We start the iteration from the first instruction.
+ it.started = true
+ }
+
+ if uint64(len(it.code)) <= it.pc {
+ // We reached the end.
+ return false
+ }
+
+ it.op = vm.OpCode(it.code[it.pc])
+ if it.op.IsPush() {
+ a := uint64(it.op) - uint64(vm.PUSH1) + 1
+ u := it.pc + 1 + a
+ if uint64(len(it.code)) <= it.pc || uint64(len(it.code)) < u {
+ it.error = fmt.Errorf("incomplete push instruction at %v", it.pc)
+ return false
+ }
+ it.arg = it.code[it.pc+1 : u]
+ } else {
+ it.arg = nil
+ }
+ return true
+}
+
+// Returns any error that may have been encountered.
+func (it *instructionIterator) Error() error {
+ return it.error
+}
+
+// Returns the PC of the current instruction.
+func (it *instructionIterator) PC() uint64 {
+ return it.pc
+}
+
+// Returns the opcode of the current instruction.
+func (it *instructionIterator) Op() vm.OpCode {
+ return it.op
+}
+
+// Returns the argument of the current instruction.
+func (it *instructionIterator) Arg() []byte {
+ return it.arg
+}
+
+// Pretty-print all disassembled EVM instructions to stdout.
+func PrintDisassembled(code string) error {
+ script, err := hex.DecodeString(code)
+ if err != nil {
+ return err
+ }
+
+ it := NewInstructionIterator(script)
+ for it.Next() {
+ if it.Arg() != nil && 0 < len(it.Arg()) {
+ fmt.Printf("%05x: %v 0x%x\n", it.PC(), it.Op(), it.Arg())
+ } else {
+ fmt.Printf("%05x: %v\n", it.PC(), it.Op())
+ }
+ }
+ return it.Error()
+}
+
+// Return all disassembled EVM instructions in human-readable format.
+func Disassemble(script []byte) ([]string, error) {
+ instrs := make([]string, 0)
+
+ it := NewInstructionIterator(script)
+ for it.Next() {
+ if it.Arg() != nil && 0 < len(it.Arg()) {
+ instrs = append(instrs, fmt.Sprintf("%05x: %v 0x%x\n", it.PC(), it.Op(), it.Arg()))
+ } else {
+ instrs = append(instrs, fmt.Sprintf("%05x: %v\n", it.PC(), it.Op()))
+ }
+ }
+ if err := it.Error(); err != nil {
+ return nil, err
+ }
+ return instrs, nil
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/core/asm/compiler.go b/vendor/github.com/ethereum/go-ethereum/core/asm/compiler.go
new file mode 100644
index 00000000..c7a54407
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/core/asm/compiler.go
@@ -0,0 +1,269 @@
+// Copyright 2017 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+package asm
+
+import (
+ "fmt"
+ "math/big"
+ "os"
+ "strings"
+
+ "github.com/ethereum/go-ethereum/common/math"
+ "github.com/ethereum/go-ethereum/core/vm"
+)
+
+// Compiler contains information about the parsed source
+// and holds the tokens for the program.
+type Compiler struct {
+ tokens []token
+ binary []interface{}
+
+ labels map[string]int
+
+ pc, pos int
+
+ debug bool
+}
+
+// newCompiler returns a new allocated compiler.
+func NewCompiler(debug bool) *Compiler {
+ return &Compiler{
+ labels: make(map[string]int),
+ debug: debug,
+ }
+}
+
+// Feed feeds tokens in to ch and are interpreted by
+// the compiler.
+//
+// feed is the first pass in the compile stage as it
+// collects the used labels in the program and keeps a
+// program counter which is used to determine the locations
+// of the jump dests. The labels can than be used in the
+// second stage to push labels and determine the right
+// position.
+func (c *Compiler) Feed(ch <-chan token) {
+ for i := range ch {
+ switch i.typ {
+ case number:
+ num := math.MustParseBig256(i.text).Bytes()
+ if len(num) == 0 {
+ num = []byte{0}
+ }
+ c.pc += len(num)
+ case stringValue:
+ c.pc += len(i.text) - 2
+ case element:
+ c.pc++
+ case labelDef:
+ c.labels[i.text] = c.pc
+ c.pc++
+ case label:
+ c.pc += 5
+ }
+
+ c.tokens = append(c.tokens, i)
+ }
+ if c.debug {
+ fmt.Fprintln(os.Stderr, "found", len(c.labels), "labels")
+ }
+}
+
+// Compile compiles the current tokens and returns a
+// binary string that can be interpreted by the EVM
+// and an error if it failed.
+//
+// compile is the second stage in the compile phase
+// which compiles the tokens to EVM instructions.
+func (c *Compiler) Compile() (string, []error) {
+ var errors []error
+ // continue looping over the tokens until
+ // the stack has been exhausted.
+ for c.pos < len(c.tokens) {
+ if err := c.compileLine(); err != nil {
+ errors = append(errors, err)
+ }
+ }
+
+ // turn the binary to hex
+ var bin string
+ for _, v := range c.binary {
+ switch v := v.(type) {
+ case vm.OpCode:
+ bin += fmt.Sprintf("%x", []byte{byte(v)})
+ case []byte:
+ bin += fmt.Sprintf("%x", v)
+ }
+ }
+ return bin, errors
+}
+
+// next returns the next token and increments the
+// position.
+func (c *Compiler) next() token {
+ token := c.tokens[c.pos]
+ c.pos++
+ return token
+}
+
+// compileLine compiles a single line instruction e.g.
+// "push 1", "jump @label".
+func (c *Compiler) compileLine() error {
+ n := c.next()
+ if n.typ != lineStart {
+ return compileErr(n, n.typ.String(), lineStart.String())
+ }
+
+ lvalue := c.next()
+ switch lvalue.typ {
+ case eof:
+ return nil
+ case element:
+ if err := c.compileElement(lvalue); err != nil {
+ return err
+ }
+ case labelDef:
+ c.compileLabel()
+ case lineEnd:
+ return nil
+ default:
+ return compileErr(lvalue, lvalue.text, fmt.Sprintf("%v or %v", labelDef, element))
+ }
+
+ if n := c.next(); n.typ != lineEnd {
+ return compileErr(n, n.text, lineEnd.String())
+ }
+
+ return nil
+}
+
+// compileNumber compiles the number to bytes
+func (c *Compiler) compileNumber(element token) (int, error) {
+ num := math.MustParseBig256(element.text).Bytes()
+ if len(num) == 0 {
+ num = []byte{0}
+ }
+ c.pushBin(num)
+ return len(num), nil
+}
+
+// compileElement compiles the element (push & label or both)
+// to a binary representation and may error if incorrect statements
+// where fed.
+func (c *Compiler) compileElement(element token) error {
+ // check for a jump. jumps must be read and compiled
+ // from right to left.
+ if isJump(element.text) {
+ rvalue := c.next()
+ switch rvalue.typ {
+ case number:
+ // TODO figure out how to return the error properly
+ c.compileNumber(rvalue)
+ case stringValue:
+ // strings are quoted, remove them.
+ c.pushBin(rvalue.text[1 : len(rvalue.text)-2])
+ case label:
+ c.pushBin(vm.PUSH4)
+ pos := big.NewInt(int64(c.labels[rvalue.text])).Bytes()
+ pos = append(make([]byte, 4-len(pos)), pos...)
+ c.pushBin(pos)
+ default:
+ return compileErr(rvalue, rvalue.text, "number, string or label")
+ }
+ // push the operation
+ c.pushBin(toBinary(element.text))
+ return nil
+ } else if isPush(element.text) {
+ // handle pushes. pushes are read from left to right.
+ var value []byte
+
+ rvalue := c.next()
+ switch rvalue.typ {
+ case number:
+ value = math.MustParseBig256(rvalue.text).Bytes()
+ if len(value) == 0 {
+ value = []byte{0}
+ }
+ case stringValue:
+ value = []byte(rvalue.text[1 : len(rvalue.text)-1])
+ case label:
+ value = make([]byte, 4)
+ copy(value, big.NewInt(int64(c.labels[rvalue.text])).Bytes())
+ default:
+ return compileErr(rvalue, rvalue.text, "number, string or label")
+ }
+
+ if len(value) > 32 {
+ return fmt.Errorf("%d type error: unsupported string or number with size > 32", rvalue.lineno)
+ }
+
+ c.pushBin(vm.OpCode(int(vm.PUSH1) - 1 + len(value)))
+ c.pushBin(value)
+ } else {
+ c.pushBin(toBinary(element.text))
+ }
+
+ return nil
+}
+
+// compileLabel pushes a jumpdest to the binary slice.
+func (c *Compiler) compileLabel() {
+ c.pushBin(vm.JUMPDEST)
+}
+
+// pushBin pushes the value v to the binary stack.
+func (c *Compiler) pushBin(v interface{}) {
+ if c.debug {
+ fmt.Printf("%d: %v\n", len(c.binary), v)
+ }
+ c.binary = append(c.binary, v)
+}
+
+// isPush returns whether the string op is either any of
+// push(N).
+func isPush(op string) bool {
+ return strings.ToUpper(op) == "PUSH"
+}
+
+// isJump returns whether the string op is jump(i)
+func isJump(op string) bool {
+ return strings.ToUpper(op) == "JUMPI" || strings.ToUpper(op) == "JUMP"
+}
+
+// toBinary converts text to a vm.OpCode
+func toBinary(text string) vm.OpCode {
+ return vm.StringToOp(strings.ToUpper(text))
+}
+
+type compileError struct {
+ got string
+ want string
+
+ lineno int
+}
+
+func (err compileError) Error() string {
+ return fmt.Sprintf("%d syntax error: unexpected %v, expected %v", err.lineno, err.got, err.want)
+}
+
+func compileErr(c token, got, want string) error {
+ return compileError{
+ got: got,
+ want: want,
+ lineno: c.lineno,
+ }
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/core/asm/lexer.go b/vendor/github.com/ethereum/go-ethereum/core/asm/lexer.go
new file mode 100644
index 00000000..00526242
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/core/asm/lexer.go
@@ -0,0 +1,291 @@
+// Copyright 2017 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+package asm
+
+import (
+ "fmt"
+ "os"
+ "strings"
+ "unicode"
+ "unicode/utf8"
+)
+
+// stateFn is used through the lifetime of the
+// lexer to parse the different values at the
+// current state.
+type stateFn func(*lexer) stateFn
+
+// token is emitted when the lexer has discovered
+// a new parsable token. These are delivered over
+// the tokens channels of the lexer
+type token struct {
+ typ tokenType
+ lineno int
+ text string
+}
+
+// tokenType are the different types the lexer
+// is able to parse and return.
+type tokenType int
+
+const (
+ eof tokenType = iota // end of file
+ lineStart // emitted when a line starts
+ lineEnd // emitted when a line ends
+ invalidStatement // any invalid statement
+ element // any element during element parsing
+ label // label is emitted when a label is found
+ labelDef // label definition is emitted when a new label is found
+ number // number is emitted when a number is found
+ stringValue // stringValue is emitted when a string has been found
+
+ Numbers = "1234567890" // characters representing any decimal number
+ HexadecimalNumbers = Numbers + "aAbBcCdDeEfF" // characters representing any hexadecimal
+ Alpha = "abcdefghijklmnopqrstuwvxyzABCDEFGHIJKLMNOPQRSTUWVXYZ" // characters representing alphanumeric
+)
+
+// String implements stringer
+func (it tokenType) String() string {
+ if int(it) > len(stringtokenTypes) {
+ return "invalid"
+ }
+ return stringtokenTypes[it]
+}
+
+var stringtokenTypes = []string{
+ eof: "EOF",
+ invalidStatement: "invalid statement",
+ element: "element",
+ lineEnd: "end of line",
+ lineStart: "new line",
+ label: "label",
+ labelDef: "label definition",
+ number: "number",
+ stringValue: "string",
+}
+
+// lexer is the basic construct for parsing
+// source code and turning them in to tokens.
+// Tokens are interpreted by the compiler.
+type lexer struct {
+ input string // input contains the source code of the program
+
+ tokens chan token // tokens is used to deliver tokens to the listener
+ state stateFn // the current state function
+
+ lineno int // current line number in the source file
+ start, pos, width int // positions for lexing and returning value
+
+ debug bool // flag for triggering debug output
+}
+
+// lex lexes the program by name with the given source. It returns a
+// channel on which the tokens are delivered.
+func Lex(source []byte, debug bool) <-chan token {
+ ch := make(chan token)
+ l := &lexer{
+ input: string(source),
+ tokens: ch,
+ state: lexLine,
+ debug: debug,
+ }
+ go func() {
+ l.emit(lineStart)
+ for l.state != nil {
+ l.state = l.state(l)
+ }
+ l.emit(eof)
+ close(l.tokens)
+ }()
+
+ return ch
+}
+
+// next returns the next rune in the program's source.
+func (l *lexer) next() (rune rune) {
+ if l.pos >= len(l.input) {
+ l.width = 0
+ return 0
+ }
+ rune, l.width = utf8.DecodeRuneInString(l.input[l.pos:])
+ l.pos += l.width
+ return rune
+}
+
+// backup backsup the last parsed element (multi-character)
+func (l *lexer) backup() {
+ l.pos -= l.width
+}
+
+// peek returns the next rune but does not advance the seeker
+func (l *lexer) peek() rune {
+ r := l.next()
+ l.backup()
+ return r
+}
+
+// ignore advances the seeker and ignores the value
+func (l *lexer) ignore() {
+ l.start = l.pos
+}
+
+// Accepts checks whether the given input matches the next rune
+func (l *lexer) accept(valid string) bool {
+ if strings.ContainsRune(valid, l.next()) {
+ return true
+ }
+
+ l.backup()
+
+ return false
+}
+
+// acceptRun will continue to advance the seeker until valid
+// can no longer be met.
+func (l *lexer) acceptRun(valid string) {
+ for strings.ContainsRune(valid, l.next()) {
+ }
+ l.backup()
+}
+
+// acceptRunUntil is the inverse of acceptRun and will continue
+// to advance the seeker until the rune has been found.
+func (l *lexer) acceptRunUntil(until rune) bool {
+ // Continues running until a rune is found
+ for i := l.next(); !strings.ContainsRune(string(until), i); i = l.next() {
+ if i == 0 {
+ return false
+ }
+ }
+
+ return true
+}
+
+// blob returns the current value
+func (l *lexer) blob() string {
+ return l.input[l.start:l.pos]
+}
+
+// Emits a new token on to token channel for processing
+func (l *lexer) emit(t tokenType) {
+ token := token{t, l.lineno, l.blob()}
+
+ if l.debug {
+ fmt.Fprintf(os.Stderr, "%04d: (%-20v) %s\n", token.lineno, token.typ, token.text)
+ }
+
+ l.tokens <- token
+ l.start = l.pos
+}
+
+// lexLine is state function for lexing lines
+func lexLine(l *lexer) stateFn {
+ for {
+ switch r := l.next(); {
+ case r == '\n':
+ l.emit(lineEnd)
+ l.ignore()
+ l.lineno++
+
+ l.emit(lineStart)
+ case r == ';' && l.peek() == ';':
+ return lexComment
+ case isSpace(r):
+ l.ignore()
+ case isLetter(r) || r == '_':
+ return lexElement
+ case isNumber(r):
+ return lexNumber
+ case r == '@':
+ l.ignore()
+ return lexLabel
+ case r == '"':
+ return lexInsideString
+ default:
+ return nil
+ }
+ }
+}
+
+// lexComment parses the current position until the end
+// of the line and discards the text.
+func lexComment(l *lexer) stateFn {
+ l.acceptRunUntil('\n')
+ l.ignore()
+
+ return lexLine
+}
+
+// lexLabel parses the current label, emits and returns
+// the lex text state function to advance the parsing
+// process.
+func lexLabel(l *lexer) stateFn {
+ l.acceptRun(Alpha + "_")
+
+ l.emit(label)
+
+ return lexLine
+}
+
+// lexInsideString lexes the inside of a string until
+// the state function finds the closing quote.
+// It returns the lex text state function.
+func lexInsideString(l *lexer) stateFn {
+ if l.acceptRunUntil('"') {
+ l.emit(stringValue)
+ }
+
+ return lexLine
+}
+
+func lexNumber(l *lexer) stateFn {
+ acceptance := Numbers
+ if l.accept("0") || l.accept("xX") {
+ acceptance = HexadecimalNumbers
+ }
+ l.acceptRun(acceptance)
+
+ l.emit(number)
+
+ return lexLine
+}
+
+func lexElement(l *lexer) stateFn {
+ l.acceptRun(Alpha + "_" + Numbers)
+
+ if l.peek() == ':' {
+ l.emit(labelDef)
+
+ l.accept(":")
+ l.ignore()
+ } else {
+ l.emit(element)
+ }
+ return lexLine
+}
+
+func isLetter(t rune) bool {
+ return unicode.IsLetter(t)
+}
+
+func isSpace(t rune) bool {
+ return unicode.IsSpace(t)
+}
+
+func isNumber(t rune) bool {
+ return unicode.IsNumber(t)
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/core/bloombits/doc.go b/vendor/github.com/ethereum/go-ethereum/core/bloombits/doc.go
new file mode 100644
index 00000000..3d159e74
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/core/bloombits/doc.go
@@ -0,0 +1,18 @@
+// Copyright 2017 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+// Package bloombits implements bloom filtering on batches of data.
+package bloombits
diff --git a/vendor/github.com/ethereum/go-ethereum/core/bloombits/generator.go b/vendor/github.com/ethereum/go-ethereum/core/bloombits/generator.go
new file mode 100644
index 00000000..ae07481a
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/core/bloombits/generator.go
@@ -0,0 +1,93 @@
+// Copyright 2017 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+package bloombits
+
+import (
+ "errors"
+
+ "github.com/ethereum/go-ethereum/core/types"
+)
+
+var (
+ // errSectionOutOfBounds is returned if the user tried to add more bloom filters
+ // to the batch than available space, or if tries to retrieve above the capacity.
+ errSectionOutOfBounds = errors.New("section out of bounds")
+
+ // errBloomBitOutOfBounds is returned if the user tried to retrieve specified
+ // bit bloom above the capacity.
+ errBloomBitOutOfBounds = errors.New("bloom bit out of bounds")
+)
+
+// Generator takes a number of bloom filters and generates the rotated bloom bits
+// to be used for batched filtering.
+type Generator struct {
+ blooms [types.BloomBitLength][]byte // Rotated blooms for per-bit matching
+ sections uint // Number of sections to batch together
+ nextSec uint // Next section to set when adding a bloom
+}
+
+// NewGenerator creates a rotated bloom generator that can iteratively fill a
+// batched bloom filter's bits.
+func NewGenerator(sections uint) (*Generator, error) {
+ if sections%8 != 0 {
+ return nil, errors.New("section count not multiple of 8")
+ }
+ b := &Generator{sections: sections}
+ for i := 0; i < types.BloomBitLength; i++ {
+ b.blooms[i] = make([]byte, sections/8)
+ }
+ return b, nil
+}
+
+// AddBloom takes a single bloom filter and sets the corresponding bit column
+// in memory accordingly.
+func (b *Generator) AddBloom(index uint, bloom types.Bloom) error {
+ // Make sure we're not adding more bloom filters than our capacity
+ if b.nextSec >= b.sections {
+ return errSectionOutOfBounds
+ }
+ if b.nextSec != index {
+ return errors.New("bloom filter with unexpected index")
+ }
+ // Rotate the bloom and insert into our collection
+ byteIndex := b.nextSec / 8
+ bitMask := byte(1) << byte(7-b.nextSec%8)
+
+ for i := 0; i < types.BloomBitLength; i++ {
+ bloomByteIndex := types.BloomByteLength - 1 - i/8
+ bloomBitMask := byte(1) << byte(i%8)
+
+ if (bloom[bloomByteIndex] & bloomBitMask) != 0 {
+ b.blooms[i][byteIndex] |= bitMask
+ }
+ }
+ b.nextSec++
+
+ return nil
+}
+
+// Bitset returns the bit vector belonging to the given bit index after all
+// blooms have been added.
+func (b *Generator) Bitset(idx uint) ([]byte, error) {
+ if b.nextSec != b.sections {
+ return nil, errors.New("bloom not fully generated yet")
+ }
+ if idx >= types.BloomBitLength {
+ return nil, errBloomBitOutOfBounds
+ }
+ return b.blooms[idx], nil
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/core/bloombits/matcher.go b/vendor/github.com/ethereum/go-ethereum/core/bloombits/matcher.go
new file mode 100644
index 00000000..3ec0d5ae
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/core/bloombits/matcher.go
@@ -0,0 +1,650 @@
+// Copyright 2017 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+package bloombits
+
+import (
+ "bytes"
+ "context"
+ "errors"
+ "math"
+ "sort"
+ "sync"
+ "sync/atomic"
+ "time"
+
+ "github.com/ethereum/go-ethereum/common/bitutil"
+ "github.com/ethereum/go-ethereum/crypto"
+)
+
+// bloomIndexes represents the bit indexes inside the bloom filter that belong
+// to some key.
+type bloomIndexes [3]uint
+
+// calcBloomIndexes returns the bloom filter bit indexes belonging to the given key.
+func calcBloomIndexes(b []byte) bloomIndexes {
+ b = crypto.Keccak256(b)
+
+ var idxs bloomIndexes
+ for i := 0; i < len(idxs); i++ {
+ idxs[i] = (uint(b[2*i])<<8)&2047 + uint(b[2*i+1])
+ }
+ return idxs
+}
+
+// partialMatches with a non-nil vector represents a section in which some sub-
+// matchers have already found potential matches. Subsequent sub-matchers will
+// binary AND their matches with this vector. If vector is nil, it represents a
+// section to be processed by the first sub-matcher.
+type partialMatches struct {
+ section uint64
+ bitset []byte
+}
+
+// Retrieval represents a request for retrieval task assignments for a given
+// bit with the given number of fetch elements, or a response for such a request.
+// It can also have the actual results set to be used as a delivery data struct.
+//
+// The contest and error fields are used by the light client to terminate matching
+// early if an error is encountered on some path of the pipeline.
+type Retrieval struct {
+ Bit uint
+ Sections []uint64
+ Bitsets [][]byte
+
+ Context context.Context
+ Error error
+}
+
+// Matcher is a pipelined system of schedulers and logic matchers which perform
+// binary AND/OR operations on the bit-streams, creating a stream of potential
+// blocks to inspect for data content.
+type Matcher struct {
+ sectionSize uint64 // Size of the data batches to filter on
+
+ filters [][]bloomIndexes // Filter the system is matching for
+ schedulers map[uint]*scheduler // Retrieval schedulers for loading bloom bits
+
+ retrievers chan chan uint // Retriever processes waiting for bit allocations
+ counters chan chan uint // Retriever processes waiting for task count reports
+ retrievals chan chan *Retrieval // Retriever processes waiting for task allocations
+ deliveries chan *Retrieval // Retriever processes waiting for task response deliveries
+
+ running uint32 // Atomic flag whether a session is live or not
+}
+
+// NewMatcher creates a new pipeline for retrieving bloom bit streams and doing
+// address and topic filtering on them. Setting a filter component to `nil` is
+// allowed and will result in that filter rule being skipped (OR 0x11...1).
+func NewMatcher(sectionSize uint64, filters [][][]byte) *Matcher {
+ // Create the matcher instance
+ m := &Matcher{
+ sectionSize: sectionSize,
+ schedulers: make(map[uint]*scheduler),
+ retrievers: make(chan chan uint),
+ counters: make(chan chan uint),
+ retrievals: make(chan chan *Retrieval),
+ deliveries: make(chan *Retrieval),
+ }
+ // Calculate the bloom bit indexes for the groups we're interested in
+ m.filters = nil
+
+ for _, filter := range filters {
+ // Gather the bit indexes of the filter rule, special casing the nil filter
+ if len(filter) == 0 {
+ continue
+ }
+ bloomBits := make([]bloomIndexes, len(filter))
+ for i, clause := range filter {
+ if clause == nil {
+ bloomBits = nil
+ break
+ }
+ bloomBits[i] = calcBloomIndexes(clause)
+ }
+ // Accumulate the filter rules if no nil rule was within
+ if bloomBits != nil {
+ m.filters = append(m.filters, bloomBits)
+ }
+ }
+ // For every bit, create a scheduler to load/download the bit vectors
+ for _, bloomIndexLists := range m.filters {
+ for _, bloomIndexList := range bloomIndexLists {
+ for _, bloomIndex := range bloomIndexList {
+ m.addScheduler(bloomIndex)
+ }
+ }
+ }
+ return m
+}
+
+// addScheduler adds a bit stream retrieval scheduler for the given bit index if
+// it has not existed before. If the bit is already selected for filtering, the
+// existing scheduler can be used.
+func (m *Matcher) addScheduler(idx uint) {
+ if _, ok := m.schedulers[idx]; ok {
+ return
+ }
+ m.schedulers[idx] = newScheduler(idx)
+}
+
+// Start starts the matching process and returns a stream of bloom matches in
+// a given range of blocks. If there are no more matches in the range, the result
+// channel is closed.
+func (m *Matcher) Start(ctx context.Context, begin, end uint64, results chan uint64) (*MatcherSession, error) {
+ // Make sure we're not creating concurrent sessions
+ if atomic.SwapUint32(&m.running, 1) == 1 {
+ return nil, errors.New("matcher already running")
+ }
+ defer atomic.StoreUint32(&m.running, 0)
+
+ // Initiate a new matching round
+ session := &MatcherSession{
+ matcher: m,
+ quit: make(chan struct{}),
+ kill: make(chan struct{}),
+ ctx: ctx,
+ }
+ for _, scheduler := range m.schedulers {
+ scheduler.reset()
+ }
+ sink := m.run(begin, end, cap(results), session)
+
+ // Read the output from the result sink and deliver to the user
+ session.pend.Add(1)
+ go func() {
+ defer session.pend.Done()
+ defer close(results)
+
+ for {
+ select {
+ case <-session.quit:
+ return
+
+ case res, ok := <-sink:
+ // New match result found
+ if !ok {
+ return
+ }
+ // Calculate the first and last blocks of the section
+ sectionStart := res.section * m.sectionSize
+
+ first := sectionStart
+ if begin > first {
+ first = begin
+ }
+ last := sectionStart + m.sectionSize - 1
+ if end < last {
+ last = end
+ }
+ // Iterate over all the blocks in the section and return the matching ones
+ for i := first; i <= last; i++ {
+ // Skip the entire byte if no matches are found inside (and we're processing an entire byte!)
+ next := res.bitset[(i-sectionStart)/8]
+ if next == 0 {
+ if i%8 == 0 {
+ i += 7
+ }
+ continue
+ }
+ // Some bit it set, do the actual submatching
+ if bit := 7 - i%8; next&(1<= req.section })
+ requests[req.bit] = append(queue[:index], append([]uint64{req.section}, queue[index:]...)...)
+
+ // If it's a new bit and we have waiting fetchers, allocate to them
+ if len(queue) == 0 {
+ assign(req.bit)
+ }
+
+ case fetcher := <-retrievers:
+ // New retriever arrived, find the lowest section-ed bit to assign
+ bit, best := uint(0), uint64(math.MaxUint64)
+ for idx := range unallocs {
+ if requests[idx][0] < best {
+ bit, best = idx, requests[idx][0]
+ }
+ }
+ // Stop tracking this bit (and alloc notifications if no more work is available)
+ delete(unallocs, bit)
+ if len(unallocs) == 0 {
+ retrievers = nil
+ }
+ allocs++
+ fetcher <- bit
+
+ case fetcher := <-m.counters:
+ // New task count request arrives, return number of items
+ fetcher <- uint(len(requests[<-fetcher]))
+
+ case fetcher := <-m.retrievals:
+ // New fetcher waiting for tasks to retrieve, assign
+ task := <-fetcher
+ if want := len(task.Sections); want >= len(requests[task.Bit]) {
+ task.Sections = requests[task.Bit]
+ delete(requests, task.Bit)
+ } else {
+ task.Sections = append(task.Sections[:0], requests[task.Bit][:want]...)
+ requests[task.Bit] = append(requests[task.Bit][:0], requests[task.Bit][want:]...)
+ }
+ fetcher <- task
+
+ // If anything was left unallocated, try to assign to someone else
+ if len(requests[task.Bit]) > 0 {
+ assign(task.Bit)
+ }
+
+ case result := <-m.deliveries:
+ // New retrieval task response from fetcher, split out missing sections and
+ // deliver complete ones
+ var (
+ sections = make([]uint64, 0, len(result.Sections))
+ bitsets = make([][]byte, 0, len(result.Bitsets))
+ missing = make([]uint64, 0, len(result.Sections))
+ )
+ for i, bitset := range result.Bitsets {
+ if len(bitset) == 0 {
+ missing = append(missing, result.Sections[i])
+ continue
+ }
+ sections = append(sections, result.Sections[i])
+ bitsets = append(bitsets, bitset)
+ }
+ m.schedulers[result.Bit].deliver(sections, bitsets)
+ allocs--
+
+ // Reschedule missing sections and allocate bit if newly available
+ if len(missing) > 0 {
+ queue := requests[result.Bit]
+ for _, section := range missing {
+ index := sort.Search(len(queue), func(i int) bool { return queue[i] >= section })
+ queue = append(queue[:index], append([]uint64{section}, queue[index:]...)...)
+ }
+ requests[result.Bit] = queue
+
+ if len(queue) == len(missing) {
+ assign(result.Bit)
+ }
+ }
+ // If we're in the process of shutting down, terminate
+ if allocs == 0 && shutdown == nil {
+ return
+ }
+ }
+ }
+}
+
+// MatcherSession is returned by a started matcher to be used as a terminator
+// for the actively running matching operation.
+type MatcherSession struct {
+ matcher *Matcher
+
+ closer sync.Once // Sync object to ensure we only ever close once
+ quit chan struct{} // Quit channel to request pipeline termination
+ kill chan struct{} // Term channel to signal non-graceful forced shutdown
+
+ ctx context.Context // Context used by the light client to abort filtering
+ err atomic.Value // Global error to track retrieval failures deep in the chain
+
+ pend sync.WaitGroup
+}
+
+// Close stops the matching process and waits for all subprocesses to terminate
+// before returning. The timeout may be used for graceful shutdown, allowing the
+// currently running retrievals to complete before this time.
+func (s *MatcherSession) Close() {
+ s.closer.Do(func() {
+ // Signal termination and wait for all goroutines to tear down
+ close(s.quit)
+ time.AfterFunc(time.Second, func() { close(s.kill) })
+ s.pend.Wait()
+ })
+}
+
+// Error returns any failure encountered during the matching session.
+func (s *MatcherSession) Error() error {
+ if err := s.err.Load(); err != nil {
+ return err.(error)
+ }
+ return nil
+}
+
+// AllocateRetrieval assigns a bloom bit index to a client process that can either
+// immediately request and fetch the section contents assigned to this bit or wait
+// a little while for more sections to be requested.
+func (s *MatcherSession) AllocateRetrieval() (uint, bool) {
+ fetcher := make(chan uint)
+
+ select {
+ case <-s.quit:
+ return 0, false
+ case s.matcher.retrievers <- fetcher:
+ bit, ok := <-fetcher
+ return bit, ok
+ }
+}
+
+// PendingSections returns the number of pending section retrievals belonging to
+// the given bloom bit index.
+func (s *MatcherSession) PendingSections(bit uint) int {
+ fetcher := make(chan uint)
+
+ select {
+ case <-s.quit:
+ return 0
+ case s.matcher.counters <- fetcher:
+ fetcher <- bit
+ return int(<-fetcher)
+ }
+}
+
+// AllocateSections assigns all or part of an already allocated bit-task queue
+// to the requesting process.
+func (s *MatcherSession) AllocateSections(bit uint, count int) []uint64 {
+ fetcher := make(chan *Retrieval)
+
+ select {
+ case <-s.quit:
+ return nil
+ case s.matcher.retrievals <- fetcher:
+ task := &Retrieval{
+ Bit: bit,
+ Sections: make([]uint64, count),
+ }
+ fetcher <- task
+ return (<-fetcher).Sections
+ }
+}
+
+// DeliverSections delivers a batch of section bit-vectors for a specific bloom
+// bit index to be injected into the processing pipeline.
+func (s *MatcherSession) DeliverSections(bit uint, sections []uint64, bitsets [][]byte) {
+ select {
+ case <-s.kill:
+ return
+ case s.matcher.deliveries <- &Retrieval{Bit: bit, Sections: sections, Bitsets: bitsets}:
+ }
+}
+
+// Multiplex polls the matcher session for retrieval tasks and multiplexes it into
+// the requested retrieval queue to be serviced together with other sessions.
+//
+// This method will block for the lifetime of the session. Even after termination
+// of the session, any request in-flight need to be responded to! Empty responses
+// are fine though in that case.
+func (s *MatcherSession) Multiplex(batch int, wait time.Duration, mux chan chan *Retrieval) {
+ for {
+ // Allocate a new bloom bit index to retrieve data for, stopping when done
+ bit, ok := s.AllocateRetrieval()
+ if !ok {
+ return
+ }
+ // Bit allocated, throttle a bit if we're below our batch limit
+ if s.PendingSections(bit) < batch {
+ select {
+ case <-s.quit:
+ // Session terminating, we can't meaningfully service, abort
+ s.AllocateSections(bit, 0)
+ s.DeliverSections(bit, []uint64{}, [][]byte{})
+ return
+
+ case <-time.After(wait):
+ // Throttling up, fetch whatever's available
+ }
+ }
+ // Allocate as much as we can handle and request servicing
+ sections := s.AllocateSections(bit, batch)
+ request := make(chan *Retrieval)
+
+ select {
+ case <-s.quit:
+ // Session terminating, we can't meaningfully service, abort
+ s.DeliverSections(bit, sections, make([][]byte, len(sections)))
+ return
+
+ case mux <- request:
+ // Retrieval accepted, something must arrive before we're aborting
+ request <- &Retrieval{Bit: bit, Sections: sections, Context: s.ctx}
+
+ result := <-request
+ if result.Error != nil {
+ s.err.Store(result.Error)
+ s.Close()
+ }
+ s.DeliverSections(result.Bit, result.Sections, result.Bitsets)
+ }
+ }
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/core/bloombits/scheduler.go b/vendor/github.com/ethereum/go-ethereum/core/bloombits/scheduler.go
new file mode 100644
index 00000000..6449c746
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/core/bloombits/scheduler.go
@@ -0,0 +1,181 @@
+// Copyright 2017 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+package bloombits
+
+import (
+ "sync"
+)
+
+// request represents a bloom retrieval task to prioritize and pull from the local
+// database or remotely from the network.
+type request struct {
+ section uint64 // Section index to retrieve the a bit-vector from
+ bit uint // Bit index within the section to retrieve the vector of
+}
+
+// response represents the state of a requested bit-vector through a scheduler.
+type response struct {
+ cached []byte // Cached bits to dedup multiple requests
+ done chan struct{} // Channel to allow waiting for completion
+}
+
+// scheduler handles the scheduling of bloom-filter retrieval operations for
+// entire section-batches belonging to a single bloom bit. Beside scheduling the
+// retrieval operations, this struct also deduplicates the requests and caches
+// the results to minimize network/database overhead even in complex filtering
+// scenarios.
+type scheduler struct {
+ bit uint // Index of the bit in the bloom filter this scheduler is responsible for
+ responses map[uint64]*response // Currently pending retrieval requests or already cached responses
+ lock sync.Mutex // Lock protecting the responses from concurrent access
+}
+
+// newScheduler creates a new bloom-filter retrieval scheduler for a specific
+// bit index.
+func newScheduler(idx uint) *scheduler {
+ return &scheduler{
+ bit: idx,
+ responses: make(map[uint64]*response),
+ }
+}
+
+// run creates a retrieval pipeline, receiving section indexes from sections and
+// returning the results in the same order through the done channel. Concurrent
+// runs of the same scheduler are allowed, leading to retrieval task deduplication.
+func (s *scheduler) run(sections chan uint64, dist chan *request, done chan []byte, quit chan struct{}, wg *sync.WaitGroup) {
+ // Create a forwarder channel between requests and responses of the same size as
+ // the distribution channel (since that will block the pipeline anyway).
+ pend := make(chan uint64, cap(dist))
+
+ // Start the pipeline schedulers to forward between user -> distributor -> user
+ wg.Add(2)
+ go s.scheduleRequests(sections, dist, pend, quit, wg)
+ go s.scheduleDeliveries(pend, done, quit, wg)
+}
+
+// reset cleans up any leftovers from previous runs. This is required before a
+// restart to ensure the no previously requested but never delivered state will
+// cause a lockup.
+func (s *scheduler) reset() {
+ s.lock.Lock()
+ defer s.lock.Unlock()
+
+ for section, res := range s.responses {
+ if res.cached == nil {
+ delete(s.responses, section)
+ }
+ }
+}
+
+// scheduleRequests reads section retrieval requests from the input channel,
+// deduplicates the stream and pushes unique retrieval tasks into the distribution
+// channel for a database or network layer to honour.
+func (s *scheduler) scheduleRequests(reqs chan uint64, dist chan *request, pend chan uint64, quit chan struct{}, wg *sync.WaitGroup) {
+ // Clean up the goroutine and pipeline when done
+ defer wg.Done()
+ defer close(pend)
+
+ // Keep reading and scheduling section requests
+ for {
+ select {
+ case <-quit:
+ return
+
+ case section, ok := <-reqs:
+ // New section retrieval requested
+ if !ok {
+ return
+ }
+ // Deduplicate retrieval requests
+ unique := false
+
+ s.lock.Lock()
+ if s.responses[section] == nil {
+ s.responses[section] = &response{
+ done: make(chan struct{}),
+ }
+ unique = true
+ }
+ s.lock.Unlock()
+
+ // Schedule the section for retrieval and notify the deliverer to expect this section
+ if unique {
+ select {
+ case <-quit:
+ return
+ case dist <- &request{bit: s.bit, section: section}:
+ }
+ }
+ select {
+ case <-quit:
+ return
+ case pend <- section:
+ }
+ }
+ }
+}
+
+// scheduleDeliveries reads section acceptance notifications and waits for them
+// to be delivered, pushing them into the output data buffer.
+func (s *scheduler) scheduleDeliveries(pend chan uint64, done chan []byte, quit chan struct{}, wg *sync.WaitGroup) {
+ // Clean up the goroutine and pipeline when done
+ defer wg.Done()
+ defer close(done)
+
+ // Keep reading notifications and scheduling deliveries
+ for {
+ select {
+ case <-quit:
+ return
+
+ case idx, ok := <-pend:
+ // New section retrieval pending
+ if !ok {
+ return
+ }
+ // Wait until the request is honoured
+ s.lock.Lock()
+ res := s.responses[idx]
+ s.lock.Unlock()
+
+ select {
+ case <-quit:
+ return
+ case <-res.done:
+ }
+ // Deliver the result
+ select {
+ case <-quit:
+ return
+ case done <- res.cached:
+ }
+ }
+ }
+}
+
+// deliver is called by the request distributor when a reply to a request arrives.
+func (s *scheduler) deliver(sections []uint64, data [][]byte) {
+ s.lock.Lock()
+ defer s.lock.Unlock()
+
+ for i, section := range sections {
+ if res := s.responses[section]; res != nil && res.cached == nil { // Avoid non-requests and double deliveries
+ res.cached = data[i]
+ close(res.done)
+ }
+ }
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/core/vm/runtime/doc.go b/vendor/github.com/ethereum/go-ethereum/core/vm/runtime/doc.go
new file mode 100644
index 00000000..a3b464a7
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/core/vm/runtime/doc.go
@@ -0,0 +1,18 @@
+// Copyright 2014 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+// Package runtime provides a basic execution model for executing EVM code.
+package runtime
diff --git a/vendor/github.com/ethereum/go-ethereum/core/vm/runtime/env.go b/vendor/github.com/ethereum/go-ethereum/core/vm/runtime/env.go
new file mode 100644
index 00000000..31c9b9cf
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/core/vm/runtime/env.go
@@ -0,0 +1,41 @@
+// Copyright 2015 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+package runtime
+
+import (
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/core"
+ "github.com/ethereum/go-ethereum/core/vm"
+)
+
+func NewEnv(cfg *Config) *vm.EVM {
+ context := vm.Context{
+ CanTransfer: core.CanTransfer,
+ Transfer: core.Transfer,
+ GetHash: func(uint64) common.Hash { return common.Hash{} },
+
+ Origin: cfg.Origin,
+ Coinbase: cfg.Coinbase,
+ BlockNumber: cfg.BlockNumber,
+ Time: cfg.Time,
+ Difficulty: cfg.Difficulty,
+ GasLimit: cfg.GasLimit,
+ GasPrice: cfg.GasPrice,
+ }
+
+ return vm.NewEVM(context, cfg.State, cfg.ChainConfig, cfg.EVMConfig)
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/core/vm/runtime/fuzz.go b/vendor/github.com/ethereum/go-ethereum/core/vm/runtime/fuzz.go
new file mode 100644
index 00000000..cb9ff08b
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/core/vm/runtime/fuzz.go
@@ -0,0 +1,36 @@
+// Copyright 2017 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+// +build gofuzz
+
+package runtime
+
+// Fuzz is the basic entry point for the go-fuzz tool
+//
+// This returns 1 for valid parsable/runable code, 0
+// for invalid opcode.
+func Fuzz(input []byte) int {
+ _, _, err := Execute(input, input, &Config{
+ GasLimit: 3000000,
+ })
+
+ // invalid opcode
+ if err != nil && len(err.Error()) > 6 && string(err.Error()[:7]) == "invalid" {
+ return 0
+ }
+
+ return 1
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/core/vm/runtime/runtime.go b/vendor/github.com/ethereum/go-ethereum/core/vm/runtime/runtime.go
new file mode 100644
index 00000000..db1f6f38
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/core/vm/runtime/runtime.go
@@ -0,0 +1,170 @@
+// Copyright 2015 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+package runtime
+
+import (
+ "math"
+ "math/big"
+ "time"
+
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/core/rawdb"
+ "github.com/ethereum/go-ethereum/core/state"
+ "github.com/ethereum/go-ethereum/core/vm"
+ "github.com/ethereum/go-ethereum/crypto"
+ "github.com/ethereum/go-ethereum/params"
+)
+
+// Config is a basic type specifying certain configuration flags for running
+// the EVM.
+type Config struct {
+ ChainConfig *params.ChainConfig
+ Difficulty *big.Int
+ Origin common.Address
+ Coinbase common.Address
+ BlockNumber *big.Int
+ Time *big.Int
+ GasLimit uint64
+ GasPrice *big.Int
+ Value *big.Int
+ Debug bool
+ EVMConfig vm.Config
+
+ State *state.StateDB
+ GetHashFn func(n uint64) common.Hash
+}
+
+// sets defaults on the config
+func setDefaults(cfg *Config) {
+ if cfg.ChainConfig == nil {
+ cfg.ChainConfig = ¶ms.ChainConfig{
+ ChainID: big.NewInt(1),
+ HomesteadBlock: new(big.Int),
+ DAOForkBlock: new(big.Int),
+ DAOForkSupport: false,
+ EIP150Block: new(big.Int),
+ EIP155Block: new(big.Int),
+ EIP158Block: new(big.Int),
+ }
+ }
+
+ if cfg.Difficulty == nil {
+ cfg.Difficulty = new(big.Int)
+ }
+ if cfg.Time == nil {
+ cfg.Time = big.NewInt(time.Now().Unix())
+ }
+ if cfg.GasLimit == 0 {
+ cfg.GasLimit = math.MaxUint64
+ }
+ if cfg.GasPrice == nil {
+ cfg.GasPrice = new(big.Int)
+ }
+ if cfg.Value == nil {
+ cfg.Value = new(big.Int)
+ }
+ if cfg.BlockNumber == nil {
+ cfg.BlockNumber = new(big.Int)
+ }
+ if cfg.GetHashFn == nil {
+ cfg.GetHashFn = func(n uint64) common.Hash {
+ return common.BytesToHash(crypto.Keccak256([]byte(new(big.Int).SetUint64(n).String())))
+ }
+ }
+}
+
+// Execute executes the code using the input as call data during the execution.
+// It returns the EVM's return value, the new state and an error if it failed.
+//
+// Executes sets up a in memory, temporarily, environment for the execution of
+// the given code. It makes sure that it's restored to it's original state afterwards.
+func Execute(code, input []byte, cfg *Config) ([]byte, *state.StateDB, error) {
+ if cfg == nil {
+ cfg = new(Config)
+ }
+ setDefaults(cfg)
+
+ if cfg.State == nil {
+ cfg.State, _ = state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()))
+ }
+ var (
+ address = common.BytesToAddress([]byte("contract"))
+ vmenv = NewEnv(cfg)
+ sender = vm.AccountRef(cfg.Origin)
+ )
+ cfg.State.CreateAccount(address)
+ // set the receiver's (the executing contract) code for execution.
+ cfg.State.SetCode(address, code)
+ // Call the code with the given configuration.
+ ret, _, err := vmenv.Call(
+ sender,
+ common.BytesToAddress([]byte("contract")),
+ input,
+ cfg.GasLimit,
+ cfg.Value,
+ )
+
+ return ret, cfg.State, err
+}
+
+// Create executes the code using the EVM create method
+func Create(input []byte, cfg *Config) ([]byte, common.Address, uint64, error) {
+ if cfg == nil {
+ cfg = new(Config)
+ }
+ setDefaults(cfg)
+
+ if cfg.State == nil {
+ cfg.State, _ = state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()))
+ }
+ var (
+ vmenv = NewEnv(cfg)
+ sender = vm.AccountRef(cfg.Origin)
+ )
+
+ // Call the code with the given configuration.
+ code, address, leftOverGas, err := vmenv.Create(
+ sender,
+ input,
+ cfg.GasLimit,
+ cfg.Value,
+ )
+ return code, address, leftOverGas, err
+}
+
+// Call executes the code given by the contract's address. It will return the
+// EVM's return value or an error if it failed.
+//
+// Call, unlike Execute, requires a config and also requires the State field to
+// be set.
+func Call(address common.Address, input []byte, cfg *Config) ([]byte, uint64, error) {
+ setDefaults(cfg)
+
+ vmenv := NewEnv(cfg)
+
+ sender := cfg.State.GetOrNewStateObject(cfg.Origin)
+ // Call the code with the given configuration.
+ ret, leftOverGas, err := vmenv.Call(
+ sender,
+ address,
+ input,
+ cfg.GasLimit,
+ cfg.Value,
+ )
+
+ return ret, leftOverGas, err
+}
diff --git a/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_add.json b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_add.json
new file mode 100644
index 00000000..c03ae96a
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_add.json
@@ -0,0 +1 @@
+[{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000002"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000006"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000002"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000006"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"000000000000000000000000000000000000000000000000000000000000000a"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"8000000000000000000000000000000000000000000000000000000000000003"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000004"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000006"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000004"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"8000000000000000000000000000000000000000000000000000000000000003"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"8000000000000000000000000000000000000000000000000000000000000004"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"8000000000000000000000000000000000000000000000000000000000000005"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000002"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"8000000000000000000000000000000000000000000000000000000000000006"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000002"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000004"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"}]
\ No newline at end of file
diff --git a/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_and.json b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_and.json
new file mode 100644
index 00000000..aba5f246
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_and.json
@@ -0,0 +1 @@
+[{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000004"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000004"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"}]
\ No newline at end of file
diff --git a/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_byte.json b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_byte.json
new file mode 100644
index 00000000..88d7c7d8
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_byte.json
@@ -0,0 +1 @@
+[{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"000000000000000000000000000000000000000000000000000000000000007f"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"00000000000000000000000000000000000000000000000000000000000000ff"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"00000000000000000000000000000000000000000000000000000000000000ff"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"000000000000000000000000000000000000000000000000000000000000007f"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"00000000000000000000000000000000000000000000000000000000000000ff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"00000000000000000000000000000000000000000000000000000000000000ff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000080"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000080"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"00000000000000000000000000000000000000000000000000000000000000ff"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"00000000000000000000000000000000000000000000000000000000000000ff"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"00000000000000000000000000000000000000000000000000000000000000ff"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"00000000000000000000000000000000000000000000000000000000000000ff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"00000000000000000000000000000000000000000000000000000000000000ff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"00000000000000000000000000000000000000000000000000000000000000ff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"}]
\ No newline at end of file
diff --git a/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_div.json b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_div.json
new file mode 100644
index 00000000..b1f9c7fb
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_div.json
@@ -0,0 +1 @@
+[{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"1999999999999999999999999999999999999999999999999999999999999999"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"1999999999999999999999999999999999999999999999999999999999999999"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"1999999999999999999999999999999999999999999999999999999999999999"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"1999999999999999999999999999999999999999999999999999999999999999"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"3333333333333333333333333333333333333333333333333333333333333332"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"3333333333333333333333333333333333333333333333333333333333333333"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000002"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000002"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"}]
\ No newline at end of file
diff --git a/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_eq.json b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_eq.json
new file mode 100644
index 00000000..937eadb0
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_eq.json
@@ -0,0 +1 @@
+[{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"}]
\ No newline at end of file
diff --git a/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_exp.json b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_exp.json
new file mode 100644
index 00000000..61818357
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_exp.json
@@ -0,0 +1 @@
+[{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000c35"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3cb"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"5c28f5c28f5c28f5c28f5c28f5c28f5c28f5c28f5c28f5c28f5c28f5c28f5c29"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"5c28f5c28f5c28f5c28f5c28f5c28f5c28f5c28f5c28f5c28f5c28f5c28f5c29"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccd"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"3333333333333333333333333333333333333333333333333333333333333333"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"58cd20afa2f05a708ede54b48d3ae685db76b3bb83cf2cf95d4e8fb00bcbe61d"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"a732df505d0fa58f7121ab4b72c5197a24894c447c30d306a2b1704ff43419e3"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccd"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"3333333333333333333333333333333333333333333333333333333333333333"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"}]
\ No newline at end of file
diff --git a/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_gt.json b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_gt.json
new file mode 100644
index 00000000..637bd3f6
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_gt.json
@@ -0,0 +1 @@
+[{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"}]
\ No newline at end of file
diff --git a/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_lt.json b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_lt.json
new file mode 100644
index 00000000..55252a4d
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_lt.json
@@ -0,0 +1 @@
+[{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"}]
\ No newline at end of file
diff --git a/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_mod.json b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_mod.json
new file mode 100644
index 00000000..192503f2
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_mod.json
@@ -0,0 +1 @@
+[{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000002"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000003"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000004"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000002"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000003"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000003"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000002"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000004"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"}]
\ No newline at end of file
diff --git a/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_mul.json b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_mul.json
new file mode 100644
index 00000000..dc44c253
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_mul.json
@@ -0,0 +1 @@
+[{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000019"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000004"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000002"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"800000000000000000000000000000000000000000000000000000000000000a"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000002"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"8000000000000000000000000000000000000000000000000000000000000002"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"8000000000000000000000000000000000000000000000000000000000000005"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"8000000000000000000000000000000000000000000000000000000000000005"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"800000000000000000000000000000000000000000000000000000000000000a"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000005"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000019"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"8000000000000000000000000000000000000000000000000000000000000002"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"}]
\ No newline at end of file
diff --git a/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_or.json b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_or.json
new file mode 100644
index 00000000..bfa561b5
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_or.json
@@ -0,0 +1 @@
+[{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"8000000000000000000000000000000000000000000000000000000000000005"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"8000000000000000000000000000000000000000000000000000000000000005"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"}]
\ No newline at end of file
diff --git a/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_sar.json b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_sar.json
new file mode 100644
index 00000000..c93abbd6
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_sar.json
@@ -0,0 +1 @@
+[{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000002"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"c000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"fc00000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"c000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"fc00000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"}]
\ No newline at end of file
diff --git a/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_sdiv.json b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_sdiv.json
new file mode 100644
index 00000000..18cb666a
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_sdiv.json
@@ -0,0 +1 @@
+[{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"1999999999999999999999999999999999999999999999999999999999999999"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"1999999999999999999999999999999999999999999999999999999999999999"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"e666666666666666666666666666666666666666666666666666666666666667"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"e666666666666666666666666666666666666666666666666666666666666667"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"e666666666666666666666666666666666666666666666666666666666666667"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"e666666666666666666666666666666666666666666666666666666666666667"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"1999999999999999999999999999999999999999999999999999999999999999"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"1999999999999999999999999999999999999999999999999999999999999999"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"8000000000000000000000000000000000000000000000000000000000000002"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"}]
\ No newline at end of file
diff --git a/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_sgt.json b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_sgt.json
new file mode 100644
index 00000000..aa581a65
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_sgt.json
@@ -0,0 +1 @@
+[{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"}]
\ No newline at end of file
diff --git a/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_shl.json b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_shl.json
new file mode 100644
index 00000000..65e9c07b
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_shl.json
@@ -0,0 +1 @@
+[{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000002"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000020"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"000000000000000000000000000000000000000000000000000000000000000a"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"00000000000000000000000000000000000000000000000000000000000000a0"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000002"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000020"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"}]
\ No newline at end of file
diff --git a/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_shr.json b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_shr.json
new file mode 100644
index 00000000..a3849135
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_shr.json
@@ -0,0 +1 @@
+[{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000002"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"4000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0400000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"4000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0400000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"}]
\ No newline at end of file
diff --git a/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_signext.json b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_signext.json
new file mode 100644
index 00000000..bdadd400
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_signext.json
@@ -0,0 +1 @@
+[{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"}]
\ No newline at end of file
diff --git a/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_slt.json b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_slt.json
new file mode 100644
index 00000000..4369b96f
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_slt.json
@@ -0,0 +1 @@
+[{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"}]
\ No newline at end of file
diff --git a/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_smod.json b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_smod.json
new file mode 100644
index 00000000..980e0341
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_smod.json
@@ -0,0 +1 @@
+[{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000002"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000002"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"}]
\ No newline at end of file
diff --git a/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_sub.json b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_sub.json
new file mode 100644
index 00000000..b3881a5a
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_sub.json
@@ -0,0 +1 @@
+[{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000004"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000002"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000003"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"8000000000000000000000000000000000000000000000000000000000000007"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000002"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000003"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000002"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"8000000000000000000000000000000000000000000000000000000000000006"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000002"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"8000000000000000000000000000000000000000000000000000000000000005"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"8000000000000000000000000000000000000000000000000000000000000004"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000006"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"000000000000000000000000000000000000000000000000000000000000000a"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"8000000000000000000000000000000000000000000000000000000000000003"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000004"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000005"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000006"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000004"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000002"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000006"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000002"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"}]
\ No newline at end of file
diff --git a/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_xor.json b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_xor.json
new file mode 100644
index 00000000..4cc2dddd
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/core/vm/testdata/testcases_xor.json
@@ -0,0 +1 @@
+[{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"0000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000004"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"},{"X":"0000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000004"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000005"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000004"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"0000000000000000000000000000000000000000000000000000000000000005","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"8000000000000000000000000000000000000000000000000000000000000005"},{"X":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"8000000000000000000000000000000000000000000000000000000000000004"},{"X":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"8000000000000000000000000000000000000000000000000000000000000005"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"8000000000000000000000000000000000000000000000000000000000000000","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"8000000000000000000000000000000000000000000000000000000000000004"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"0000000000000000000000000000000000000000000000000000000000000001"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"},{"X":"8000000000000000000000000000000000000000000000000000000000000001","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"8000000000000000000000000000000000000000000000000000000000000005"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000004"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000000"},{"X":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000004"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000000","Expected":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000001","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"0000000000000000000000000000000000000000000000000000000000000005","Expected":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe","Expected":"8000000000000000000000000000000000000000000000000000000000000001"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"8000000000000000000000000000000000000000000000000000000000000000"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000000","Expected":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"8000000000000000000000000000000000000000000000000000000000000001","Expected":"7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb","Expected":"0000000000000000000000000000000000000000000000000000000000000004"},{"X":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Y":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","Expected":"0000000000000000000000000000000000000000000000000000000000000000"}]
\ No newline at end of file
diff --git a/vendor/github.com/ethereum/go-ethereum/crypto/secp256k1/libsecp256k1/.gitignore b/vendor/github.com/ethereum/go-ethereum/crypto/secp256k1/libsecp256k1/.gitignore
new file mode 100644
index 00000000..87fea161
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/crypto/secp256k1/libsecp256k1/.gitignore
@@ -0,0 +1,49 @@
+bench_inv
+bench_ecdh
+bench_sign
+bench_verify
+bench_schnorr_verify
+bench_recover
+bench_internal
+tests
+exhaustive_tests
+gen_context
+*.exe
+*.so
+*.a
+!.gitignore
+
+Makefile
+configure
+.libs/
+Makefile.in
+aclocal.m4
+autom4te.cache/
+config.log
+config.status
+*.tar.gz
+*.la
+libtool
+.deps/
+.dirstamp
+*.lo
+*.o
+*~
+src/libsecp256k1-config.h
+src/libsecp256k1-config.h.in
+src/ecmult_static_context.h
+build-aux/config.guess
+build-aux/config.sub
+build-aux/depcomp
+build-aux/install-sh
+build-aux/ltmain.sh
+build-aux/m4/libtool.m4
+build-aux/m4/lt~obsolete.m4
+build-aux/m4/ltoptions.m4
+build-aux/m4/ltsugar.m4
+build-aux/m4/ltversion.m4
+build-aux/missing
+build-aux/compile
+build-aux/test-driver
+src/stamp-h1
+libsecp256k1.pc
diff --git a/vendor/github.com/ethereum/go-ethereum/crypto/secp256k1/libsecp256k1/.travis.yml b/vendor/github.com/ethereum/go-ethereum/crypto/secp256k1/libsecp256k1/.travis.yml
new file mode 100644
index 00000000..24395292
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/crypto/secp256k1/libsecp256k1/.travis.yml
@@ -0,0 +1,69 @@
+language: c
+sudo: false
+addons:
+ apt:
+ packages: libgmp-dev
+compiler:
+ - clang
+ - gcc
+cache:
+ directories:
+ - src/java/guava/
+env:
+ global:
+ - FIELD=auto BIGNUM=auto SCALAR=auto ENDOMORPHISM=no STATICPRECOMPUTATION=yes ASM=no BUILD=check EXTRAFLAGS= HOST= ECDH=no RECOVERY=no EXPERIMENTAL=no
+ - GUAVA_URL=https://search.maven.org/remotecontent?filepath=com/google/guava/guava/18.0/guava-18.0.jar GUAVA_JAR=src/java/guava/guava-18.0.jar
+ matrix:
+ - SCALAR=32bit RECOVERY=yes
+ - SCALAR=32bit FIELD=32bit ECDH=yes EXPERIMENTAL=yes
+ - SCALAR=64bit
+ - FIELD=64bit RECOVERY=yes
+ - FIELD=64bit ENDOMORPHISM=yes
+ - FIELD=64bit ENDOMORPHISM=yes ECDH=yes EXPERIMENTAL=yes
+ - FIELD=64bit ASM=x86_64
+ - FIELD=64bit ENDOMORPHISM=yes ASM=x86_64
+ - FIELD=32bit ENDOMORPHISM=yes
+ - BIGNUM=no
+ - BIGNUM=no ENDOMORPHISM=yes RECOVERY=yes EXPERIMENTAL=yes
+ - BIGNUM=no STATICPRECOMPUTATION=no
+ - BUILD=distcheck
+ - EXTRAFLAGS=CPPFLAGS=-DDETERMINISTIC
+ - EXTRAFLAGS=CFLAGS=-O0
+ - BUILD=check-java ECDH=yes EXPERIMENTAL=yes
+matrix:
+ fast_finish: true
+ include:
+ - compiler: clang
+ env: HOST=i686-linux-gnu ENDOMORPHISM=yes
+ addons:
+ apt:
+ packages:
+ - gcc-multilib
+ - libgmp-dev:i386
+ - compiler: clang
+ env: HOST=i686-linux-gnu
+ addons:
+ apt:
+ packages:
+ - gcc-multilib
+ - compiler: gcc
+ env: HOST=i686-linux-gnu ENDOMORPHISM=yes
+ addons:
+ apt:
+ packages:
+ - gcc-multilib
+ - compiler: gcc
+ env: HOST=i686-linux-gnu
+ addons:
+ apt:
+ packages:
+ - gcc-multilib
+ - libgmp-dev:i386
+before_install: mkdir -p `dirname $GUAVA_JAR`
+install: if [ ! -f $GUAVA_JAR ]; then wget $GUAVA_URL -O $GUAVA_JAR; fi
+before_script: ./autogen.sh
+script:
+ - if [ -n "$HOST" ]; then export USE_HOST="--host=$HOST"; fi
+ - if [ "x$HOST" = "xi686-linux-gnu" ]; then export CC="$CC -m32"; fi
+ - ./configure --enable-experimental=$EXPERIMENTAL --enable-endomorphism=$ENDOMORPHISM --with-field=$FIELD --with-bignum=$BIGNUM --with-scalar=$SCALAR --enable-ecmult-static-precomputation=$STATICPRECOMPUTATION --enable-module-ecdh=$ECDH --enable-module-recovery=$RECOVERY $EXTRAFLAGS $USE_HOST && make -j2 $BUILD
+os: linux
diff --git a/vendor/github.com/ethereum/go-ethereum/crypto/secp256k1/libsecp256k1/Makefile.am b/vendor/github.com/ethereum/go-ethereum/crypto/secp256k1/libsecp256k1/Makefile.am
new file mode 100644
index 00000000..c071fbe2
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/crypto/secp256k1/libsecp256k1/Makefile.am
@@ -0,0 +1,177 @@
+ACLOCAL_AMFLAGS = -I build-aux/m4
+
+lib_LTLIBRARIES = libsecp256k1.la
+if USE_JNI
+JNI_LIB = libsecp256k1_jni.la
+noinst_LTLIBRARIES = $(JNI_LIB)
+else
+JNI_LIB =
+endif
+include_HEADERS = include/secp256k1.h
+noinst_HEADERS =
+noinst_HEADERS += src/scalar.h
+noinst_HEADERS += src/scalar_4x64.h
+noinst_HEADERS += src/scalar_8x32.h
+noinst_HEADERS += src/scalar_low.h
+noinst_HEADERS += src/scalar_impl.h
+noinst_HEADERS += src/scalar_4x64_impl.h
+noinst_HEADERS += src/scalar_8x32_impl.h
+noinst_HEADERS += src/scalar_low_impl.h
+noinst_HEADERS += src/group.h
+noinst_HEADERS += src/group_impl.h
+noinst_HEADERS += src/num_gmp.h
+noinst_HEADERS += src/num_gmp_impl.h
+noinst_HEADERS += src/ecdsa.h
+noinst_HEADERS += src/ecdsa_impl.h
+noinst_HEADERS += src/eckey.h
+noinst_HEADERS += src/eckey_impl.h
+noinst_HEADERS += src/ecmult.h
+noinst_HEADERS += src/ecmult_impl.h
+noinst_HEADERS += src/ecmult_const.h
+noinst_HEADERS += src/ecmult_const_impl.h
+noinst_HEADERS += src/ecmult_gen.h
+noinst_HEADERS += src/ecmult_gen_impl.h
+noinst_HEADERS += src/num.h
+noinst_HEADERS += src/num_impl.h
+noinst_HEADERS += src/field_10x26.h
+noinst_HEADERS += src/field_10x26_impl.h
+noinst_HEADERS += src/field_5x52.h
+noinst_HEADERS += src/field_5x52_impl.h
+noinst_HEADERS += src/field_5x52_int128_impl.h
+noinst_HEADERS += src/field_5x52_asm_impl.h
+noinst_HEADERS += src/java/org_bitcoin_NativeSecp256k1.h
+noinst_HEADERS += src/java/org_bitcoin_Secp256k1Context.h
+noinst_HEADERS += src/util.h
+noinst_HEADERS += src/testrand.h
+noinst_HEADERS += src/testrand_impl.h
+noinst_HEADERS += src/hash.h
+noinst_HEADERS += src/hash_impl.h
+noinst_HEADERS += src/field.h
+noinst_HEADERS += src/field_impl.h
+noinst_HEADERS += src/bench.h
+noinst_HEADERS += contrib/lax_der_parsing.h
+noinst_HEADERS += contrib/lax_der_parsing.c
+noinst_HEADERS += contrib/lax_der_privatekey_parsing.h
+noinst_HEADERS += contrib/lax_der_privatekey_parsing.c
+
+if USE_EXTERNAL_ASM
+COMMON_LIB = libsecp256k1_common.la
+noinst_LTLIBRARIES = $(COMMON_LIB)
+else
+COMMON_LIB =
+endif
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = libsecp256k1.pc
+
+if USE_EXTERNAL_ASM
+if USE_ASM_ARM
+libsecp256k1_common_la_SOURCES = src/asm/field_10x26_arm.s
+endif
+endif
+
+libsecp256k1_la_SOURCES = src/secp256k1.c
+libsecp256k1_la_CPPFLAGS = -DSECP256K1_BUILD -I$(top_srcdir)/include -I$(top_srcdir)/src $(SECP_INCLUDES)
+libsecp256k1_la_LIBADD = $(JNI_LIB) $(SECP_LIBS) $(COMMON_LIB)
+
+libsecp256k1_jni_la_SOURCES = src/java/org_bitcoin_NativeSecp256k1.c src/java/org_bitcoin_Secp256k1Context.c
+libsecp256k1_jni_la_CPPFLAGS = -DSECP256K1_BUILD $(JNI_INCLUDES)
+
+noinst_PROGRAMS =
+if USE_BENCHMARK
+noinst_PROGRAMS += bench_verify bench_sign bench_internal
+bench_verify_SOURCES = src/bench_verify.c
+bench_verify_LDADD = libsecp256k1.la $(SECP_LIBS) $(SECP_TEST_LIBS) $(COMMON_LIB)
+bench_sign_SOURCES = src/bench_sign.c
+bench_sign_LDADD = libsecp256k1.la $(SECP_LIBS) $(SECP_TEST_LIBS) $(COMMON_LIB)
+bench_internal_SOURCES = src/bench_internal.c
+bench_internal_LDADD = $(SECP_LIBS) $(COMMON_LIB)
+bench_internal_CPPFLAGS = -DSECP256K1_BUILD $(SECP_INCLUDES)
+endif
+
+TESTS =
+if USE_TESTS
+noinst_PROGRAMS += tests
+tests_SOURCES = src/tests.c
+tests_CPPFLAGS = -DSECP256K1_BUILD -I$(top_srcdir)/src -I$(top_srcdir)/include $(SECP_INCLUDES) $(SECP_TEST_INCLUDES)
+if !ENABLE_COVERAGE
+tests_CPPFLAGS += -DVERIFY
+endif
+tests_LDADD = $(SECP_LIBS) $(SECP_TEST_LIBS) $(COMMON_LIB)
+tests_LDFLAGS = -static
+TESTS += tests
+endif
+
+if USE_EXHAUSTIVE_TESTS
+noinst_PROGRAMS += exhaustive_tests
+exhaustive_tests_SOURCES = src/tests_exhaustive.c
+exhaustive_tests_CPPFLAGS = -DSECP256K1_BUILD -I$(top_srcdir)/src $(SECP_INCLUDES)
+if !ENABLE_COVERAGE
+exhaustive_tests_CPPFLAGS += -DVERIFY
+endif
+exhaustive_tests_LDADD = $(SECP_LIBS)
+exhaustive_tests_LDFLAGS = -static
+TESTS += exhaustive_tests
+endif
+
+JAVAROOT=src/java
+JAVAORG=org/bitcoin
+JAVA_GUAVA=$(srcdir)/$(JAVAROOT)/guava/guava-18.0.jar
+CLASSPATH_ENV=CLASSPATH=$(JAVA_GUAVA)
+JAVA_FILES= \
+ $(JAVAROOT)/$(JAVAORG)/NativeSecp256k1.java \
+ $(JAVAROOT)/$(JAVAORG)/NativeSecp256k1Test.java \
+ $(JAVAROOT)/$(JAVAORG)/NativeSecp256k1Util.java \
+ $(JAVAROOT)/$(JAVAORG)/Secp256k1Context.java
+
+if USE_JNI
+
+$(JAVA_GUAVA):
+ @echo Guava is missing. Fetch it via: \
+ wget https://search.maven.org/remotecontent?filepath=com/google/guava/guava/18.0/guava-18.0.jar -O $(@)
+ @false
+
+.stamp-java: $(JAVA_FILES)
+ @echo Compiling $^
+ $(AM_V_at)$(CLASSPATH_ENV) javac $^
+ @touch $@
+
+if USE_TESTS
+
+check-java: libsecp256k1.la $(JAVA_GUAVA) .stamp-java
+ $(AM_V_at)java -Djava.library.path="./:./src:./src/.libs:.libs/" -cp "$(JAVA_GUAVA):$(JAVAROOT)" $(JAVAORG)/NativeSecp256k1Test
+
+endif
+endif
+
+if USE_ECMULT_STATIC_PRECOMPUTATION
+CPPFLAGS_FOR_BUILD +=-I$(top_srcdir)
+CFLAGS_FOR_BUILD += -Wall -Wextra -Wno-unused-function
+
+gen_context_OBJECTS = gen_context.o
+gen_context_BIN = gen_context$(BUILD_EXEEXT)
+gen_%.o: src/gen_%.c
+ $(CC_FOR_BUILD) $(CPPFLAGS_FOR_BUILD) $(CFLAGS_FOR_BUILD) -c $< -o $@
+
+$(gen_context_BIN): $(gen_context_OBJECTS)
+ $(CC_FOR_BUILD) $^ -o $@
+
+$(libsecp256k1_la_OBJECTS): src/ecmult_static_context.h
+$(tests_OBJECTS): src/ecmult_static_context.h
+$(bench_internal_OBJECTS): src/ecmult_static_context.h
+
+src/ecmult_static_context.h: $(gen_context_BIN)
+ ./$(gen_context_BIN)
+
+CLEANFILES = $(gen_context_BIN) src/ecmult_static_context.h $(JAVAROOT)/$(JAVAORG)/*.class .stamp-java
+endif
+
+EXTRA_DIST = autogen.sh src/gen_context.c src/basic-config.h $(JAVA_FILES)
+
+if ENABLE_MODULE_ECDH
+include src/modules/ecdh/Makefile.am.include
+endif
+
+if ENABLE_MODULE_RECOVERY
+include src/modules/recovery/Makefile.am.include
+endif
diff --git a/vendor/github.com/ethereum/go-ethereum/crypto/secp256k1/libsecp256k1/README.md b/vendor/github.com/ethereum/go-ethereum/crypto/secp256k1/libsecp256k1/README.md
new file mode 100644
index 00000000..8cd344ea
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/crypto/secp256k1/libsecp256k1/README.md
@@ -0,0 +1,61 @@
+libsecp256k1
+============
+
+[![Build Status](https://travis-ci.org/bitcoin-core/secp256k1.svg?branch=master)](https://travis-ci.org/bitcoin-core/secp256k1)
+
+Optimized C library for EC operations on curve secp256k1.
+
+This library is a work in progress and is being used to research best practices. Use at your own risk.
+
+Features:
+* secp256k1 ECDSA signing/verification and key generation.
+* Adding/multiplying private/public keys.
+* Serialization/parsing of private keys, public keys, signatures.
+* Constant time, constant memory access signing and pubkey generation.
+* Derandomized DSA (via RFC6979 or with a caller provided function.)
+* Very efficient implementation.
+
+Implementation details
+----------------------
+
+* General
+ * No runtime heap allocation.
+ * Extensive testing infrastructure.
+ * Structured to facilitate review and analysis.
+ * Intended to be portable to any system with a C89 compiler and uint64_t support.
+ * Expose only higher level interfaces to minimize the API surface and improve application security. ("Be difficult to use insecurely.")
+* Field operations
+ * Optimized implementation of arithmetic modulo the curve's field size (2^256 - 0x1000003D1).
+ * Using 5 52-bit limbs (including hand-optimized assembly for x86_64, by Diederik Huys).
+ * Using 10 26-bit limbs.
+ * Field inverses and square roots using a sliding window over blocks of 1s (by Peter Dettman).
+* Scalar operations
+ * Optimized implementation without data-dependent branches of arithmetic modulo the curve's order.
+ * Using 4 64-bit limbs (relying on __int128 support in the compiler).
+ * Using 8 32-bit limbs.
+* Group operations
+ * Point addition formula specifically simplified for the curve equation (y^2 = x^3 + 7).
+ * Use addition between points in Jacobian and affine coordinates where possible.
+ * Use a unified addition/doubling formula where necessary to avoid data-dependent branches.
+ * Point/x comparison without a field inversion by comparison in the Jacobian coordinate space.
+* Point multiplication for verification (a*P + b*G).
+ * Use wNAF notation for point multiplicands.
+ * Use a much larger window for multiples of G, using precomputed multiples.
+ * Use Shamir's trick to do the multiplication with the public key and the generator simultaneously.
+ * Optionally (off by default) use secp256k1's efficiently-computable endomorphism to split the P multiplicand into 2 half-sized ones.
+* Point multiplication for signing
+ * Use a precomputed table of multiples of powers of 16 multiplied with the generator, so general multiplication becomes a series of additions.
+ * Access the table with branch-free conditional moves so memory access is uniform.
+ * No data-dependent branches
+ * The precomputed tables add and eventually subtract points for which no known scalar (private key) is known, preventing even an attacker with control over the private key used to control the data internally.
+
+Build steps
+-----------
+
+libsecp256k1 is built using autotools:
+
+ $ ./autogen.sh
+ $ ./configure
+ $ make
+ $ ./tests
+ $ sudo make install # optional
diff --git a/vendor/github.com/ethereum/go-ethereum/crypto/secp256k1/libsecp256k1/TODO b/vendor/github.com/ethereum/go-ethereum/crypto/secp256k1/libsecp256k1/TODO
new file mode 100644
index 00000000..a300e1c5
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/crypto/secp256k1/libsecp256k1/TODO
@@ -0,0 +1,3 @@
+* Unit tests for fieldelem/groupelem, including ones intended to
+ trigger fieldelem's boundary cases.
+* Complete constant-time operations for signing/keygen
diff --git a/vendor/github.com/ethereum/go-ethereum/crypto/secp256k1/libsecp256k1/autogen.sh b/vendor/github.com/ethereum/go-ethereum/crypto/secp256k1/libsecp256k1/autogen.sh
new file mode 100755
index 00000000..65286b93
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/crypto/secp256k1/libsecp256k1/autogen.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+set -e
+autoreconf -if --warnings=all
diff --git a/vendor/github.com/ethereum/go-ethereum/crypto/secp256k1/libsecp256k1/build-aux/m4/ax_jni_include_dir.m4 b/vendor/github.com/ethereum/go-ethereum/crypto/secp256k1/libsecp256k1/build-aux/m4/ax_jni_include_dir.m4
new file mode 100644
index 00000000..1fc36276
--- /dev/null
+++ b/vendor/github.com/ethereum/go-ethereum/crypto/secp256k1/libsecp256k1/build-aux/m4/ax_jni_include_dir.m4
@@ -0,0 +1,140 @@
+# ===========================================================================
+# http://www.gnu.org/software/autoconf-archive/ax_jni_include_dir.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_JNI_INCLUDE_DIR
+#
+# DESCRIPTION
+#
+# AX_JNI_INCLUDE_DIR finds include directories needed for compiling
+# programs using the JNI interface.
+#
+# JNI include directories are usually in the Java distribution. This is
+# deduced from the value of $JAVA_HOME, $JAVAC, or the path to "javac", in
+# that order. When this macro completes, a list of directories is left in
+# the variable JNI_INCLUDE_DIRS.
+#
+# Example usage follows:
+#
+# AX_JNI_INCLUDE_DIR
+#
+# for JNI_INCLUDE_DIR in $JNI_INCLUDE_DIRS
+# do
+# CPPFLAGS="$CPPFLAGS -I$JNI_INCLUDE_DIR"
+# done
+#
+# If you want to force a specific compiler:
+#
+# - at the configure.in level, set JAVAC=yourcompiler before calling
+# AX_JNI_INCLUDE_DIR
+#
+# - at the configure level, setenv JAVAC
+#
+# Note: This macro can work with the autoconf M4 macros for Java programs.
+# This particular macro is not part of the original set of macros.
+#
+# LICENSE
+#
+# Copyright (c) 2008 Don Anderson
+#
+# Copying and distribution of this file, with or without modification, are
+# permitted in any medium without royalty provided the copyright notice
+# and this notice are preserved. This file is offered as-is, without any
+# warranty.
+
+#serial 10
+
+AU_ALIAS([AC_JNI_INCLUDE_DIR], [AX_JNI_INCLUDE_DIR])
+AC_DEFUN([AX_JNI_INCLUDE_DIR],[
+
+JNI_INCLUDE_DIRS=""
+
+if test "x$JAVA_HOME" != x; then
+ _JTOPDIR="$JAVA_HOME"
+else
+ if test "x$JAVAC" = x; then
+ JAVAC=javac
+ fi
+ AC_PATH_PROG([_ACJNI_JAVAC], [$JAVAC], [no])
+ if test "x$_ACJNI_JAVAC" = xno; then
+ AC_MSG_WARN([cannot find JDK; try setting \$JAVAC or \$JAVA_HOME])
+ fi
+ _ACJNI_FOLLOW_SYMLINKS("$_ACJNI_JAVAC")
+ _JTOPDIR=`echo "$_ACJNI_FOLLOWED" | sed -e 's://*:/:g' -e 's:/[[^/]]*$::'`
+fi
+
+case "$host_os" in
+ darwin*) _JTOPDIR=`echo "$_JTOPDIR" | sed -e 's:/[[^/]]*$::'`
+ _JINC="$_JTOPDIR/Headers";;
+ *) _JINC="$_JTOPDIR/include";;
+esac
+_AS_ECHO_LOG([_JTOPDIR=$_JTOPDIR])
+_AS_ECHO_LOG([_JINC=$_JINC])
+
+# On Mac OS X 10.6.4, jni.h is a symlink:
+# /System/Library/Frameworks/JavaVM.framework/Versions/Current/Headers/jni.h
+# -> ../../CurrentJDK/Headers/jni.h.
+
+AC_CACHE_CHECK(jni headers, ac_cv_jni_header_path,
+[
+if test -f "$_JINC/jni.h"; then
+ ac_cv_jni_header_path="$_JINC"
+ JNI_INCLUDE_DIRS="$JNI_INCLUDE_DIRS $ac_cv_jni_header_path"
+else
+ _JTOPDIR=`echo "$_JTOPDIR" | sed -e 's:/[[^/]]*$::'`
+ if test -f "$_JTOPDIR/include/jni.h"; then
+ ac_cv_jni_header_path="$_JTOPDIR/include"
+ JNI_INCLUDE_DIRS="$JNI_INCLUDE_DIRS $ac_cv_jni_header_path"
+ else
+ ac_cv_jni_header_path=none
+ fi
+fi
+])
+
+
+
+# get the likely subdirectories for system specific java includes
+case "$host_os" in
+bsdi*) _JNI_INC_SUBDIRS="bsdos";;
+darwin*) _JNI_INC_SUBDIRS="darwin";;
+freebsd*) _JNI_INC_SUBDIRS="freebsd";;
+linux*) _JNI_INC_SUBDIRS="linux genunix";;
+osf*) _JNI_INC_SUBDIRS="alpha";;
+solaris*) _JNI_INC_SUBDIRS="solaris";;
+mingw*) _JNI_INC_SUBDIRS="win32";;
+cygwin*) _JNI_INC_SUBDIRS="win32";;
+*) _JNI_INC_SUBDIRS="genunix";;
+esac
+
+if test "x$ac_cv_jni_header_path" != "xnone"; then
+ # add any subdirectories that are present
+ for JINCSUBDIR in $_JNI_INC_SUBDIRS
+ do
+ if test -d "$_JTOPDIR/include/$JINCSUBDIR"; then
+ JNI_INCLUDE_DIRS="$JNI_INCLUDE_DIRS $_JTOPDIR/include/$JINCSUBDIR"
+ fi
+ done
+fi
+])
+
+# _ACJNI_FOLLOW_SYMLINKS
+# Follows symbolic links on ]