chainlib-eth

Ethereum implementation of the chainlib interface
Info | Log | Files | Refs | README | LICENSE

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()