test_abi.py (7080B)
1 # standard imports 2 import unittest 3 import logging 4 import os 5 6 # local imports 7 from chainlib.eth.contract import ( 8 ABIContractEncoder, 9 ABIContractType, 10 ) 11 12 logging.basicConfig(level=logging.DEBUG) 13 logg = logging.getLogger() 14 15 16 class TestContract(unittest.TestCase): 17 18 def test_abi_param(self): 19 e = ABIContractEncoder() 20 e.uint256(42) 21 e.bytes32('0x666f6f') 22 e.address('0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef') 23 e.method('foo') 24 e.typ(ABIContractType.UINT256) 25 e.typ(ABIContractType.BYTES32) 26 e.typ(ABIContractType.ADDRESS) 27 28 self.assertEqual(e.types[0], ABIContractType.UINT256) 29 self.assertEqual(e.types[1], ABIContractType.BYTES32) 30 self.assertEqual(e.types[2], ABIContractType.ADDRESS) 31 self.assertEqual(e.contents[0], '000000000000000000000000000000000000000000000000000000000000002a') 32 self.assertEqual(e.contents[1], '0000000000000000000000000000000000000000000000000000000000666f6f') 33 self.assertEqual(e.contents[2], '000000000000000000000000deadbeefdeadbeefdeadbeefdeadbeefdeadbeef') 34 35 self.assertEqual(e.get(), 'a08f54bb000000000000000000000000000000000000000000000000000000000000002a0000000000000000000000000000000000000000000000000000000000666f6f000000000000000000000000deadbeefdeadbeefdeadbeefdeadbeefdeadbeef') 36 37 38 def test_abi_uintn(self): 39 e = ABIContractEncoder() 40 e.uintn(42, 16) 41 e.uintn(13, 32) 42 e.uintn(666, 64) 43 e.uintn(1337, 128) 44 e.method('foo') 45 e.typ(ABIContractType.UINT16) 46 e.typ(ABIContractType.UINT32) 47 e.typ(ABIContractType.UINT64) 48 e.typ(ABIContractType.UINT128) 49 50 self.assertEqual(e.contents[0], '000000000000000000000000000000000000000000000000000000000000002a') 51 self.assertEqual(e.contents[1], '000000000000000000000000000000000000000000000000000000000000000d') 52 self.assertEqual(e.contents[2], '000000000000000000000000000000000000000000000000000000000000029a') 53 self.assertEqual(e.contents[3], '0000000000000000000000000000000000000000000000000000000000000539') 54 55 self.assertEqual(e.get(), '5e260038000000000000000000000000000000000000000000000000000000000000002a000000000000000000000000000000000000000000000000000000000000000d000000000000000000000000000000000000000000000000000000000000029a0000000000000000000000000000000000000000000000000000000000000539') 56 57 58 def test_abi_bytes(self): 59 e = ABIContractEncoder() 60 e.bytes('deadbeef') 61 e.method('foo') 62 e.typ(ABIContractType.BYTES) 63 self.assertEqual(e.get(), '30c8d1da00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000004deadbeef00000000000000000000000000000000000000000000000000000000') 64 65 66 def test_abi_string(self): 67 e = ABIContractEncoder() 68 e.string('deadbeef') 69 e.method('foo') 70 e.typ(ABIContractType.STRING) 71 self.assertEqual(e.get(), 'f31a6969000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000086465616462656566000000000000000000000000000000000000000000000000') 72 73 74 def test_abi_tuple(self): 75 e = ABIContractEncoder() 76 e.typ(ABIContractType.STRING) 77 e.typ(ABIContractType.BYTES32) 78 e.string('deadbeef') 79 e.bytes32('666f6f') 80 81 ee = ABIContractEncoder() 82 ee.method('foo') 83 ee.typ(e) 84 ee.typ(ABIContractType.UINT256) 85 ee.tuple(e) 86 ee.uint256(42) 87 88 self.assertEqual(ee.get_method(), 'foo((string,bytes32),uint256)') 89 r = ee.get() 90 self.assertEqual(r[:8], '7bab4ebd') 91 r = r[8:] 92 valid = [ 93 '0000000000000000000000000000000000000000000000000000000000000040', 94 '000000000000000000000000000000000000000000000000000000000000002a', 95 '0000000000000000000000000000000000000000000000000000000000000040', 96 '0000000000000000000000000000000000000000000000000000000000666f6f', 97 '0000000000000000000000000000000000000000000000000000000000000008', 98 '6465616462656566000000000000000000000000000000000000000000000000', 99 ] 100 101 i = 0 102 c = 0 103 while c < len(r): 104 v = r[c:c+64] 105 logg.debug('check position {} {}'.format((i*32).to_bytes(2, byteorder='big').hex(), v)) 106 self.assertEqual(v, valid[i]) 107 c += 64 108 i += 1 109 110 111 def test_abi_tuple_embedded(self): 112 a = os.urandom(20) 113 ea = ABIContractEncoder() 114 ea.typ(ABIContractType.STRING) 115 ea.typ(ABIContractType.ADDRESS) 116 ea.string('foo@bar.com') 117 ea.address(a.hex()) 118 119 b = os.urandom(20) 120 eb = ABIContractEncoder() 121 eb.typ(ABIContractType.STRING) 122 eb.typ(ABIContractType.ADDRESS) 123 eb.string('baz@xyzzy.org') 124 eb.address(b.hex()) 125 126 ee = ABIContractEncoder() 127 ee.typ(ea) 128 ee.typ(eb) 129 ee.typ(ABIContractType.STRING) 130 ee.tuple(ea) 131 ee.tuple(eb) 132 ee.string('barbarbar') 133 134 e = ABIContractEncoder() 135 e.method('foo') 136 e.typ(ee) 137 e.typ(ABIContractType.UINT256) 138 e.tuple(ee) 139 e.uint256(42) 140 141 self.assertEqual(e.get_method(), 'foo(((string,address),(string,address),string),uint256)') 142 r = e.get() 143 print(r) 144 self.assertEqual(r[:8], '8cd9051d') 145 r = r[8:] 146 147 valid = [ 148 '0000000000000000000000000000000000000000000000000000000000000040', 149 '000000000000000000000000000000000000000000000000000000000000002a', 150 '0000000000000000000000000000000000000000000000000000000000000060', 151 '00000000000000000000000000000000000000000000000000000000000000e0', 152 '0000000000000000000000000000000000000000000000000000000000000160', 153 '0000000000000000000000000000000000000000000000000000000000000040', 154 '000000000000000000000000' + a.hex(), 155 '000000000000000000000000000000000000000000000000000000000000000b', 156 '666f6f406261722e636f6d000000000000000000000000000000000000000000', 157 '0000000000000000000000000000000000000000000000000000000000000040', 158 '000000000000000000000000' + b.hex(), 159 '000000000000000000000000000000000000000000000000000000000000000d', 160 '62617a4078797a7a792e6f726700000000000000000000000000000000000000', 161 '0000000000000000000000000000000000000000000000000000000000000009', 162 '6261726261726261720000000000000000000000000000000000000000000000', 163 ] 164 165 i = 0 166 c = 0 167 while c < len(r): 168 v = r[c:c+64] 169 logg.debug('check position {} {}'.format((i*32).to_bytes(2, byteorder='big').hex(), v)) 170 self.assertEqual(v, valid[i]) 171 c += 64 172 i += 1 173 174 175 176 if __name__ == '__main__': 177 unittest.main()