diff --git a/.gitignore b/.gitignore index 37371a3..3a3c8f3 100644 --- a/.gitignore +++ b/.gitignore @@ -109,3 +109,6 @@ fabric.properties # VS Code .vscode/ + +# Debug +.debug \ No newline at end of file diff --git a/README.md b/README.md index 581e638..87b3d34 100644 --- a/README.md +++ b/README.md @@ -5,41 +5,2264 @@ [![Build Status](https://circleci.com/gh/ethereum/web3.py.svg?style=shield)](https://github.com/PlatONnetwork/client-sdk-python) -A Python implementation of [web3.js](https://github.com/ethereum/web3.js) +## Description -* Python 3.6+ support +client-sdk-python is a python sdk serving the Platon underlying chain. Interact with the underlying chain through the web3 object. At the bottom level, it communicates with local nodes through RPC calls. client-sdk-python can connect to any PlatON node that exposes the RPC interface. -Read more in the [documentation on ReadTheDocs](http://web3py.readthedocs.io/). [View the change log on Github](docs/releases.rst). +The main functions are used to obtain block data, send transactions, interact with smart contracts, and other applications. -## Quickstart +[client-sdk-python download link](https://github.com/PlatONnetwork/client-sdk-python) -```python +## Quick start + +### Special Note + +- chain_id + + - 210309 is the chain id of the development network. + + - 100 is the chain id of the main net. + +### One part: installation + +#### **1** Python environment requirements + + Support Python 3.6+ version + +#### **2** You can use pip to install directly: + + pip install client-sdk-python + + + Or download the code and use it in the python editor. git bash pull the source code, the following operations + + git clone -b 0.15.1-develop https://github.com/PlatONnetwork/client-sdk-python.git + +> Where `0.15.1-develop` is the currently used branch. + +### Second part: use + +#### **1** Web3 mode + + Communication between Platon nodes through P2PMessage. The built-in Web3 mode is used between the node and the python sdk to send JSON-RPC requests, and connect to the node through HTTP, websocket, IPC and other methods. + +#### **2** Node connection + +- Take HTTP connection as an example, connect to a Platon node + + ```python + w3 = Web3(HTTPProvider("http://localhost:6789"),chain_id = 100) + platon = PlatON(w3) + print(w3.isConnected()) + ``` + + Where localhost:6789 is a node Url of Platon, please enter the Url of the accessible Platon node. + + platon is an instance of the platON class. + +- Take Websocket connection as an example + + code show as below: + + ```python + w3 = Web3(WebsocketProvider("ws://localhost:6790"),chain_id = 100) + platon = PlatON(w3) + print(w3.isConnected()) + ``` + +- Take IPC connection as an example + + code show as below: + + ```python + w3 = Web3(IPCProvider("./platon.ipc"),chain_id = 100) + platon = PlatON(w3) + print(w3.isConnected()) + ``` + + + + +#### 3 Basic API + +##### Basic type encoding and decoding + +- Web3.toBytes() + Convert the input parameters to Bytes + transfer: + + ```python + >>> Web3.toBytes(0) + b'\x00' + >>> Web3.toBytes(0x000F) + b'\x0f' + ``` + +- Web3.toHex() + + Convert the input parameter to hexadecimal + + transfer: + + ``` + >>> Web3.toHex(b'\x00\x0F') + '0x000f' + >>> Web3.toHex(False) + '0x0' + ``` + +- Web3.toInt() + + Convert the input parameter to an integer + + transfer: + + ```python + >>> Web3.toInt(0x000F) + 15 + >>> Web3.toInt(b'\x00\x0F') + 15 + ``` + +- Web3.toJSON() + + Convert the input parameters to json format + + transfer + + ```python + >>> Web3.toJSON(3) + '3' + >>> Web3.toJSON({'one': 1}) + '{"one": 1}' + ``` + +- Web3.toText() + + Convert input parameters to string format + + transfer + + ```python + >>> Web3.toText(b'cowm\xc3\xb6') + 'cowmö' + >>> Web3.toText(hexstr='0x636f776dc3b6') + 'cowmö' + ``` +##### Address detection + +- Web3.isAddress() + + Check whether the input parameter is an approved address form + + transfer + + ```python + >>> Web3.isAddress('0xd3CdA913deB6f67967B99D67aCDFa1712C293601') + True + ``` + +- Web3.isChecksumAddress() + + Check the checksum of the specified address, and return false for non-checksum addresses + + ```python + >>> Web3.isChecksumAddress('0xd3CdA913deB6f67967B99D67aCDFa1712C293601') + True + >>> Web3.isChecksumAddress('0xd3cda913deb6f67967b99d67acdfa1712c293601') + False + ``` + +##### Cryptographic hash + +- - Web3.sha3() + + Compile input parameters to Keccak-256 + + transfer: + + ```python + >>> Web3.sha3(0x678901) + HexBytes('0x77cf3b4c68ccdb65991397e7b93111e0f7d863df3b26ebb053d0857e26486e6a') + >>> Web3.sha3(text='txt') + HexBytes('0xd7278090a36507640ea6b7a0034b69b0d240766fa3f98e3722be93c613b29d2e') + ``` + +- Web3.soliditySha3() + + Compile the input abi_type and value to Keccak-256 + + parameter: + + - value: true value. + - abi_type: a list of strings in solidity format equal to value. + + transfer + + ```python + >>> Web3.solidityKeccak(['uint8[]'], [[97, 98, 99]]) + HexBytes("0x233002c671295529bcc50b76a2ef2b0de2dac2d93945fca745255de1a9e4017e") + + >>> Web3.solidityKeccak(['address'], ["0x49EdDD3769c0712032808D86597B84ac5c2F5614"]) + HexBytes("0x2ff37b5607484cd4eecf6d13292e22bd6e5401eaffcc07e279583bc742c68882") + ``` + + +#### **4** On-chain query api + +After successfully connecting with the nodes on the Platon chain, you can query the relevant information of the nodes on the chain through the api in platon + +##### (1) platon.blockNumber + + Returns the current block number. + + Return value: + + An AttributeDict object whose parsed value is the number of the most recent block, Number type. + + + +##### (2) platon.syncing + + Used to check whether the node is currently synchronized with the network. + + return value: + + An AttributeDict object with a resolved value of `Object` or `Bool`. If the node has not been synchronized with the network, + It returns false, otherwise it returns a synchronization object with the following properties: + - startingBlock-Number: Synchronization starting block number. + - currentBlock-Number: currently synchronized block number. + + - highestBlock-Number: Estimated target synchronization block number. + + - knownStates-Number: Estimated states to be downloaded. + + - pulledStates-Number: downloaded states. + + +##### (3) platon.gasPrice + + Used to get the current gas price, which is determined by the median gas price of several recent blocks. + + Return value: + + An AttributeDict object whose parsed value is a string representing the current gas price, in VON. + + +##### (4) platon.accounts + + The method returns the list of accounts controlled by the current node. + + return value + + An AttributeDict object whose resolved value is an array of account addresses. + + +##### (5) platon.evidences + + Returns the storage content at the specified location of the account address. + + return value + + An AttributeDict object whose resolution value is the stored content of the account address. + + +##### (6) platon.consensusStatus + + Returns the consensus status information of the block tree where the current node is located. + + return value + + An AttributeDict object whose value is the public status information of all the blocks in the block tree. + + +##### (7) platon.getBalance(address) + + Used to get the balance of a specific account address in a specified block. + + parameter: + + - `address`: String-the account address to check the balance, bech32 address format, the beginning of lax is the testnet, the beginning of lat is the mainnet + + return value: + + An AttributeDict object whose parsed value is the balance string of the specified account address, in units of VON + +Some code examples: + +```python from client_sdk_python import Web3, HTTPProvider from client_sdk_python.eth import PlatON from hexbytes import HexBytes -# get blockNumber -w3 = Web3(HTTPProvider("http://localhost:6789")) +# get blockNumber syncing gasPrice accounts evidences consensusStatus +w3 = Web3(HTTPProvider("http://localhost:6789"),chain_id = 100) platon = PlatON(w3) block_number = platon.blockNumber print(block_number) +print(platon.syncing) +print(platon.gasPrice) +print(platon.accounts) +print(platon.evidences) +print(platon.consensusStatus) # get Balance -address = '0x493301712671Ada506ba6Ca7891F436D29185821' +address ='lax1yjjzvjph3tw4h2quw6mse25y492xy7fzwdtqja' balance = platon.getBalance(address) print(balance) +#Output +385274 +False +100000000 +['lax1yjjzvjph3tw4h2quw6mse25y492xy7fzwdtqja','lax1qqqjkfwu854vf3ze2dpy5gctmxy3gdgzsngj66'] +{} +AttributeDict({'blockTree': AttributeDict({'root': AttributeDict({'viewNumber': 22,'blockHash': '0x92e3229453574aa2a7120e3b0dd44d3b1b304465418a129dcc72124414b9674d','blockNumber': 392226,'receiveTime': 05'receiveTime': 58.440430021+08:00','qc': AttributeDict({'epoch': 1569,'viewNumber': 22,'blockHash': '0x92e3229453574aa2a7120e3b0dd44d3b1b304465418a129dcc72124414b9674d','blockNumber': 392 5226,'blockIndex': 392 5226, '0x83a517492b9052de25d3b88413f070becff1e995167094b33805bfaf640b8d1499304844f08478f0525c44e7eb9ec70000000000000000000000000000000000', 'validatorSet': '_xxx'}), 'parentHash': '0x0000000000000000000000000000000000000000000000000000000000000000', 'childrenHash': [ '0x69ea999a1bdb006bb9b113f20047a3d3ae79433abc1749e4fa1ec4082dcb0e90']}), 'blocks': AttributeDict ({' 392226 ': AttributeDict ({' 0x92e3229453574aa2a7120e3b0dd44d3b1b304465418a129dcc72124414b9674d ': AttributeDict({'viewNumber': 22,'blockHash': '0x92e3229453574aa2a7120e3b0dd44d3b1b304465418a129dcc72124414b9674 d','blockNumber': 392226,'receiveTime': '2020-09-15T18:05:58.440430021+08:00','qc': AttributeDict({'epoch': 1569,'viewNumber': 22,'blockHash ':' 0x92e3229453574aa2a7120e3b0dd44d3b1b304465418a129dcc72124414b9674d ',' blockNumber ': 392226,' blockIndex ': 5,' signature ':' 0x83a517492b9052de25d3b88413f070becff1e995167094b33805bfaf640b8d1499304844f08478f0525c44e7eb9ec70000000000000000000000000000000000 ',' validatorSet ':' _xxx '}),' parentHash ':' 0x0000000000000000000000000000000000000000000000000000000000000000 ',' childrenHash ': [' 0x69ea999a1bdb006bb9b113f20047a3d3ae79433abc1749e4fa1ec4082dcb0e90 ']})}),' 392227 ': AttributeDict ({' 0x69ea999a1bdb006bb9b113f20047a3d3ae79433abc1749e4fa1ec4082dcb0e90 ': AttributeDict ({' viewNumber ': 22,' blockHash ':' 0x69ea999a1bdb006bb9b113f20047a3d3ae79433abc1749e4fa1ec4082dcb0e90 ',' blockNumber ': 392227,' receiveTime ':' 2020-09 -15T18:05:59.542161134+08:00','qc': AttributeDict({'epoch': 1569,'viewNumber': 22,'blockHash': '0x69ea999a1bdb006bb9b113f20047a3d3ae7 9433abc1749e4fa1ec4082dcb0e90 ',' blockNumber ': 392227,' blockIndex ': 6,' signature ':' 0x50bcc710ac0182f311065dfcb4b1c8b378788bcfe53217d6f5b29e3178508bec5557eaf7e9d360930c69c43a091e5f1800000000000000000000000000000000 ',' validatorSet ':' _xxx '}),' parentHash ':' 0x92e3229453574aa2a7120e3b0dd44d3b1b304465418a129dcc72124414b9674d ',' childrenHash ': [' 0x314adeb1ded15f49579ae2bc44d0b060d1d57905e9ddcd8da8ad1628bbee5294 '] }))), '392228': AttributeDict({'0x314adeb1ded15f49579ae2bc44d0b060d1d57905e9ddcd8da8ad1628bbee5294': AttributeDict({'viewNumber': 22,'blockHash': '0x314adeb1ded15f49579ae2bc44d0b060d1d57905e9ddcd8da8ad1628bbee5294': AttributeDict({'viewNumber': 22,'blockHash': '0x314adeb1cd8294228' 06:00.642317619+08:00','qc': AttributeDict({'epoch': 1569,'viewNumber': 22,'blockHash': '0x314adeb1ded15f49579ae2bc44d0b060d1d57905e9ddcd8da8ad1628bbee5294','signatureNumber': 392 7,228,'blockIndex ': '0x505b4a9e0ed0cb3e26b2b327013bcde06350c7b2926126bbaa02417e386b0ecddc31201ec66e8a29e3c86714d669899000 000000000000000000000000000000','validatorSet':'_xxx'}),'parentHash': '0x69ea999a1bdb006bb9b113f20047a3d3ae79433abc1749e4fa1ec4082dcb0e90','childrenHash': []}))))))','StateDictview(AttributeDict') 'epoch': 1569,'viewNumber': 22,'executing': AttributeDict({'blockIndex': 7,'finish': True}),'viewchange': AttributeDict({'viewchanges': AttributeDict({})} ),'lastViewchange': None,'hadSendPrepareVote': AttributeDict({'votes': [AttributeDict({'epoch': 1569,'viewNumber': 22,'blockHash': '0x201c9308eb4e0af12b98d64694837db7a5ab430blockaa71'857db90392' blockIndex': 0,'validatorIndex': 1,'parentQC': AttributeDict(('epoch': 1569,'viewNumber': 21,'blockHash': '0x3cc758aa857621036e55cede20943ffd1a3b7e1ebc38dffcc690d4804f706dd0','blockNumber': 392220,'blockNumber': 392220, 'signature': '0xb3a89b39e9345d37ea7db2985132a3adb55abb906cd975f137eb608f55be7ea7657b0ecc0ccfa99d3caebb25a088018d00000000000000000000000000000000','validatorSet':'_xxx')),'s ignature ':' 0x599205f55ce4a191405fb5c7ad4a3961bb95a93206525b8218777023f47114a611146a40921f537478339375844cb10b00000000000000000000000000000000 '}), AttributeDict ({' epoch ': 1569,' viewNumber ': 22,' blockHash ':' 0xf6fff5626fc1fd235bb224a4d1b3f68ccd1f9f56ad4d6dff428d33b4b10cff7f ',' blockNumber ': 392222,' blockIndex ': 1,' validatorIndex ': 1, 'parentQC': AttributeDict ({ 'epoch': 1569, 'viewNumber': 22, 'blockHash': '0x201c9308eb4e0af12b98d64694837db7a59780ab430aa71ccfdb90741d41f857', 'blockNumber': 392221, 'blockIndex': 0, 'signature': '0xfbb64c0d0bd6f531f4d9b6303e9b3ede59deb1877c7a31bd95c0403dcfc32dec7b8060574616d500735a2d734d21e90300000000000000000000000000000000', 'validatorSet' : '_xxx'}), 'signature': '0x422a227b80667cd3f38ff794018ad3f634c0aafdbcc08a9dddff2f46b3d66f829c217dca47add729817a72dae169040000000000000000000000000000000000'}), AttributeDict ({ 'epoch': 1569, 'viewNumber': 22, 'blockHash': '0x812e7f19e6a281928ac77767300560b8ed633d0c45f53a05b0163ea807898913', 'blockNumber': 392223, 'b lockIndex': 2,'validatorIndex': 1,'parentQC': AttributeDict({'epoch': 1569,'viewNumber': 22,'blockHash': '0xf6fff5626fc1fd235bb224a4d1b3f68ccd1f9f56ad4d6dff428d33b4b10cff7f','Numberblock'Index: 392 1, 'signature': '0x5dc7f6461e0078b7e474badc1f7b3e0716b52f5f2f2ddcd144bd738e74246d1e5ee3780e0d4f7771b3afd5b10936019500000000000000000000000000000000', 'validatorSet': '_xxx'}), 'signature': '0xaedbc8885b066d99905c7813302ce699b895761a1b4ab83efda28dc3b5901b585ada31df67932b68e52edd663f651e9200000000000000000000000000000000'}), AttributeDict ({ 'epoch': 1569, 'viewNumber': 22, 'blockHash': '0x45f49937c4ea54b08d36fc1223fd819da11f709b3827217225c235a0ef9f89a8' ,'blockNumber': 392224,'blockIndex': 3,'validatorIndex': 1,'parentQC': AttributeDict({'epoch': 1569,'viewNumber': 22,'blockHash': '0x812e7f19e6a281928ac77767300560b8ed633d0c45f53a05b0163eablockNumber'913:', 392223,'blockIndex': 2,'signature': '0xd3a08cfd6c3a166e1d31dd1e58bb9eb1960bebcfc38ebad0eb0880ab30b2e46112c5 14980050159ad235615381ac820d00000000000000000000000000000000 ',' validatorSet ':' _xxx '}),' signature ':' 0xb52fb84d8ea31918023e695fe3619ba14a1335f6455e6ab42559d7e38c9bcef8105d7c33d433f6fb7eb8d524b1afb58b00000000000000000000000000000000 '}), AttributeDict ({' epoch ': 1569,' viewNumber ': 22,' blockHash ':' 0x0341dcfab2ee1ec61b5cd380bd8445ab0a17819cc4f633ee0b3a4ca211c717f9 ',' blockNumber ': 392225,'blockIndex': 4,'validatorIndex': 1,'parentQC': AttributeDict({'epoch': 1569,'viewNumber': 22,'blockHash': '0x45f49937c4ea54b08d36fc1223fd819da11f709b3827217225c235a0ef9f89'blockIndex: 392224,'blockNumber : 3, 'signature': '0xd837920786bce9ea276ff3a6505dc8f48db18e9f7f4272b66dff966c904bbb83adb70f425af9c99a30957a8eae3cf30b00000000000000000000000000000000', 'validatorSet': '_xxx'}), 'signature': '0x63dd1a1f8331320b2be8bd04abb2bae53f67fe9c14f70863723a86ccf329d4d95c9446aae360081935df5a7f2ac8681300000000000000000000000000000000'}), AttributeDict ({ 'epoch': 1569, 'viewNumber': 22, 'blockHash': '0x9 2e3229453574aa2a7120e3b0dd44d3b1b304465418a129dcc72124414b9674d','blockNumber': 392226,'blockIndex': 5,'validatorIndex': 1,'parentQC': Dict(('epochAttribute': 1569,'viewNumber': 22,'blockHec7, 11, 37, 14b,, and ': 392225,' blockIndex ': 4,' signature ':' 0x442a6e1c25857ac5ba84b16ab38918fba3c75681dcf623eacf23d5dbafd293cd0d3d617472e60dccd343c9444c4d428500000000000000000000000000000000 ',' validatorSet ':' x_xx '}),' signature ':' 0xf885e975ff4828d1f10be4dd61b7cd4e362d0f4a0b79af9d7a2ac34209341ee79d76281ec7b205f834e5c2c00c0c398800000000000000000000000000000000 '}), AttributeDict ({' epoch ': 1569,' viewNumber ' : 22,'blockHash': '0x69ea999a1bdb006bb9b113f20047a3d3ae79433abc1749e4fa1ec4082dcb0e90','blockNumber': 392227,'blockIndex': 6,'validatorIndex': 1,'parentQC': AttributeDict({'epochNumberHash': 22 ': '0x92e3229453574aa2a7120e3b0dd44d3b1b304465418a129dcc72124414b9674d','blockNumber': 392226,'blockInde x ': 5,' signature ':' 0x83a517492b9052de25d3b88413f070becff1e995167094b33805bfaf640b8d1499304844f08478f0525c44e7eb9ec70000000000000000000000000000000000 ',' validatorSet ':' _xxx '}),' signature ':' 0xbe0d77590be62ec7cb0f5fd2dd5071aa6d97e8b909fd05cc80f10e6e58f0984adeeb7078f2c9a99e4a08e00102d4209900000000000000000000000000000000 '}), AttributeDict ({' epoch ': 1569,' viewNumber ': 22,' blockHash ': '0x314adeb1ded15f49579ae2bc44d0b060d1d57905e9ddcd8da8ad1628bbee5294','blockNumber': 392228,'blockIndex': 7,'validatorIndex': 1,'parentQC': AttributebbDict({'epoch': 1569, '0be69a , 'blockNumber': 392227, 'blockIndex': 6, 'signature': '0x50bcc710ac0182f311065dfcb4b1c8b378788bcfe53217d6f5b29e3178508bec5557eaf7e9d360930c69c43a091e5f1800000000000000000000000000000000', 'validatorSet': '_xxx'}), 'signature': '0x7305573c2655de2537e744ef1411ea55e450f8879a19274ede2455f40975f59c1b9df25d3e311464fb5cbd2398fcd48600000000000 000000000000000000000'})]}),'pendingPrepareVote': AttributeDict({'votes': []}),'viewBlocks': AttributeDict({'0': AttributeDict({'hash': '0x201c9308eb4e0af12b98d64694837db7a59780',number 392221,'blockIndex': 0}), '1': AttributeDict({'hash': '0xf6fff5626fc1fd235bb224a4d1b3f68ccd1f9f56ad4d6dff428d33b4b10cff7f','number': 392222,'blockIndex': AttributeDict( 1)),'number': 392222,'hash'{ 1}), '0x812e7f19e6a281928ac77767300560b8ed633d0c45f53a05b0163ea807898913','number': 392223,'blockIndex': 2}), '3': AttributeDict({'hash': '0x45f49937c4ea70954b08d36fc1223fdefda11f2242222423a2709'b3827225 : AttributeDict({'hash': '0x0341dcfab2ee1ec61b5cd380bd8445ab0a17819cc4f633ee0b3a4ca211c717f9','number': 392225,'blockIndex': 4)), '5': AttributeDict({'hash': '0x0341dcfab2ee1ec61b5cd380bd8445ab0a17819cc4f633ee0b3a4ca211c717f9','number': 392225,'blockIndex': 4}), '5': AttributeDict({'hash': : 5}), '6': AttributeDict({'hash': '0x69ea999a1bdb006bb9b113f20047a3d3ae79433abc1749e4f a1ec4082dcb0e90','number': 392227,'blockIndex': 6}), '7': AttributeDict({'hash': '0x314adeb1ded15f49579ae2bc44d0b060d1d57905e9ddcd8da8ad1628bbee5294','number': 392228,'block})','view 7Qcs')' ': AttributeDict({'maxIndex': 7,'qcs': AttributeDict({'0': AttributeDict({'epoch': 1569,'viewNumber': 22,'blockHash': '0x201c9308eb4e0af12b98d64694837db7a58579780ab430aa71ccfdb90741d41f:', '221 , 'blockIndex': 0, 'signature': '0xfbb64c0d0bd6f531f4d9b6303e9b3ede59deb1877c7a31bd95c0403dcfc32dec7b8060574616d500735a2d734d21e90300000000000000000000000000000000', 'validatorSet': '_xxx'}), '1': AttributeDict ({ 'epoch': 1569, 'viewNumber': 22, 'blockHash': '0xf6fff5626fc1fd235bb224a4d1b3f68ccd1f9f56ad4d6dff428d33b4b10cff7f ','blockNumber': 392222,'blockIndex': 1,'signature': '0x5dc7f6461e0078b7e474badc1f7b3e0716b52f5f2f2ddcd144bd738e74246d1e5ee3780e0d4f7771b3afd5b109' : 22, 'blockHash': '0x812e7f19e6a281928ac77767300560b8ed633d0c45f53a05b0163ea807898913', 'blockNumber': 392223, 'blockIndex': 2, 'signature': '0xd3a08cfd6c3a166e1d31dd1e58bb9eb1960bebcfc38ebad0eb0880ab30b2e46112c514980050159ad235615381ac820d00000000000000000000000000000000', 'validatorSet': '_xxx'}), '3': AttributeDict ({ 'epoch ': 1569,' viewNumber ': 22,' blockHash ':' 0x45f49937c4ea54b08d36fc1223fd819da11f709b3827217225c235a0ef9f89a8 ',' blockNumber ': 392224,' blockIndex ': 3,' signature ':' 0xd837920786bce9ea276ff3a6505dc8f48db18e9f7f4272b66dff966c904bbb83adb70f425af9c99a30957a8eae3cf30b00000000000000000000000000000000 ',' validatorSet ':' _xxx '}),' 4 ': AttributeDict ({' epoch ': 1569,' viewNumber ': 22,' blockHash ':' 0x0341dcfab2ee1ec61b5cd380bd8445ab0a17819cc4f633ee0b3a4ca211c717f9 ',' blockNumber ': 392225,' blockIndex ': 4,' signature ':' 0x442a6e1c25857ac5ba84b16ab38918fba3c75681dcf623eacf23d5dbafd293cd0d3d617472e60dccd343c9444c4d428500000000000000000000000000000000 ',' validatorSet ':' x_xx'}), '5': AttributeDict ({ 'epoch': 1569, 'viewNumber': 22, 'blockHash': '0x92e3229453574aa2a7120e3b0dd44d3b1b304465418a129dcc72124414b9674d', 'blockNumber': 392226, 'blockIndex': 5, 'signature': '0x83a517492b9052de25d3b88413f070becff1e995167094b33805bfaf640b8d1499304844f08478f0525c44e7eb9ec70000000000000000000000000000000000', 'validatorSet' :'_xxx')), '6': AttributeDict(('epoch': 1569,'viewNumber': 22,'blockHash': '0x69ea999a1bdb006bb9b113f20047a3d3ae79433abc1749e4fa1ec4082dcb0e90','blockNumber': 392 6,227,'blockIndex': '0x50bcc710ac0182f311065dfcb4b1c8b378788bcfe53217d6f5b29e3178508bec5557eaf7e9d360930c69c43a091e5f1800000000000000000000000000000000', 'validatorSet': '_xxx'}), '7': AttributeDict ({ 'epoch': 1569, 'viewNumber': 22, 'blockHash': '0x314adeb1ded15f49579ae2bc44d0b060d1d57905e9ddcd8da8ad1628bbee5294', 'blockNumber': 392228, 'blockIndex' : 7,'signature': '0x505b4a9e0ed0cb3e26b2b327013bcde06350c7b2926126bbaa02417e386b0ecddc31201ec66e8a29e3c86714d669899000000000000000 000000000000000000','validatorSet':'_xxx'}))))),'viewVotes': AttributeDict({'votes': AttributeDict({'0': AttributeDict({'votes': AttributeDict({'1': AttributeDict ({'epoch': 1569,'viewNumber': 22,'blockHash': '0x201c9308eb4e0af12b98d64694837db7a59780ab430aa71ccfdb90741d41f857','blockNumber': 392221,'blockIndex': 0,'validatorIndex': 1,'parentQC': AttributeDict({'epoch' : 1569, 'viewNumber': 21, 'blockHash': '0x3cc758aa857621036e55cede20943ffd1a3b7e1ebc38dffcc690d4804f706dd0', 'blockNumber': 392220, 'blockIndex': 9, 'signature': '0xb3a89b39e9345d37ea7db2985132a3adb55abb906cd975f137eb608f55be7ea7657b0ecc0ccfa99d3caebb25a088018d00000000000000000000000000000000', 'validatorSet': '_xxx'}), 'signature' : '0x599205f55ce4a191405fb5c7ad4a3961bb95a93206525b8218777023f47114a611146a40921f537478339375844cb10b00000000000000000000000000000000')))))), '1': AttributeDict({'votes': AttributeDict({'1', '224xfbbd': AttributeDict({'1', '224xfbbd': AttributeDict('1') 1f9f56ad4d6dff428d33b4b10cff7f','blockNumber': 392222,'blockIndex': 1,'validatorIndex': 1,'parentQC': AttributeDict({'epoch': 1569,'viewNumber': 22,'blockHash': '0x201c9308eb4e0af12b71ccf'85790741db ': 392221,' blockIndex ': 0,' signature ':' 0xfbb64c0d0bd6f531f4d9b6303e9b3ede59deb1877c7a31bd95c0403dcfc32dec7b8060574616d500735a2d734d21e90300000000000000000000000000000000 ',' validatorSet ':' _xxx '}),' signature ':' 0x422a227b80667cd3f38ff794018ad3f634c0aafdbcc08a9dddff2f46b3d66f829c217dca47add729817a72dae169040000000000000000000000000000000000 '})})}),' 2 ': AttributeDict ({' votes': AttributeDict(('1': AttributeDict(('epoch': 1569,'viewNumber': 22,'blockHash': '0x812e7f19e6a281928ac77767300560b8ed633d0c45f53a05b0163ea807898913','blockNumber': 392223,'blockHash': 1,'validatorIndex': 1, ,'parentQC': AttributeDict(('epoch': 1569,'viewNumber': 22,'blockHash': '0xf6fff5626fc1fd235bb224a4d1b3f68ccd1f9f56ad4d6dff428d33b4b10cff7f','blockNumber' : 392222, 'blockIndex': 1, 'signature': '0x5dc7f6461e0078b7e474badc1f7b3e0716b52f5f2f2ddcd144bd738e74246d1e5ee3780e0d4f7771b3afd5b10936019500000000000000000000000000000000', 'validatorSet': '_xxx'}), 'signature': '0xaedbc8885b066d99905c7813302ce699b895761a1b4ab83efda28dc3b5901b585ada31df67932b68e52edd663f651e9200000000000000000000000000000000'})})}), '3': AttributeDict ({ 'votes ': AttributeDict({'1': AttributeDict({'epoch': 1569,'viewNumber': 22,'blockHash': '0x45f49937c4ea54b08d36fc1223fd819da11f709b3827217225c235a0ef9f89a8','blockNumber': 392224,'blockNumber': 3, 'parentQC': AttributeDict ({ 'epoch': 1569, 'viewNumber': 22, 'blockHash': '0x812e7f19e6a281928ac77767300560b8ed633d0c45f53a05b0163ea807898913', 'blockNumber': 392223, 'blockIndex': 2, 'signature': '0xd3a08cfd6c3a166e1d31dd1e58bb9eb1960bebcfc38ebad0eb0880ab30b2e46112c514980050159ad235615381ac820d00000000000000000000000000000000', 'validatorSet' :'_xxx'}),'signature': '0xb52fb84d8ea31918023e695fe3619ba14a 1335f6455e6ab42559d7e38c9bcef8105d7c33d433f6fb7eb8d524b1afb58b00000000000000000000000000000000 '})})}),' 4 ': AttributeDict ({' votes': AttributeDict ({ '1': AttributeDict ({ 'epoch': 1569, 'viewNumber': 22, 'blockHash': '0x0341dcfab2ee1ec61b5cd380bd8445ab0a17819cc4f633ee0b3a4ca211c717f9', 'blockNumber': 392225,'blockIndex': 4,'validatorIndex': 1,'parentQC': AttributeDict({'epoch': 1569,'viewNumber': 22,'blockHash': '0x45f49937c4ea54b08d36fc1223fd819da11f709b3827217225c235'a0,392224 , 'blockIndex': 3, 'signature': '0xd837920786bce9ea276ff3a6505dc8f48db18e9f7f4272b66dff966c904bbb83adb70f425af9c99a30957a8eae3cf30b00000000000000000000000000000000', 'validatorSet': '_xxx'}), 'signature': '0x63dd1a1f8331320b2be8bd04abb2bae53f67fe9c14f70863723a86ccf329d4d95c9446aae360081935df5a7f2ac8681300000000000000000000000000000000'})})}), '5': AttributeDict ({ 'votes': AttributeDict({'1': AttributeDict({'epoch': 1569,'viewNumber': 22,'blockHash': '0x92e3229453574aa2a7120e3b0dd44d3b1b 304465418a129dcc72124414b9674d','blockNumber': 392226,'blockIndex': 5,'validatorIndex': 1,'parentQC': AttributeDict({'epoch': 1569,'viewNumber': 22,'blockHash': '0x0341dcfab2ee1ec61b5cd380bd38445ab0a71711 ': 392225,' blockIndex ': 4,' signature ':' 0x442a6e1c25857ac5ba84b16ab38918fba3c75681dcf623eacf23d5dbafd293cd0d3d617472e60dccd343c9444c4d428500000000000000000000000000000000 ',' validatorSet ':' x_xx '}),' signature ':' 0xf885e975ff4828d1f10be4dd61b7cd4e362d0f4a0b79af9d7a2ac34209341ee79d76281ec7b205f834e5c2c00c0c398800000000000000000000000000000000 '})})}),' 6 ': AttributeDict ({' votes': AttributeDict({'1': AttributeDict({'epoch': 1569,'viewNumber': 22,'blockHash': '0x69ea999a1bdb006bb9b113f20047a3d3ae79433abc1749e4fa1ec4082dcb0e90','blockNumber': 392 6,227,'validatorIndex': 392 6,227, ,'parentQC': AttributeDict(('epoch': 1569,'viewNumber': 22,'blockHash': '0x92e3229453574aa2a7120e3b0dd44d3b1b304465418a129dcc72124414b9674d','blockNumber' : 392226, 'blockIndex': 5, 'signature': '0x83a517492b9052de25d3b88413f070becff1e995167094b33805bfaf640b8d1499304844f08478f0525c44e7eb9ec70000000000000000000000000000000000', 'validatorSet': '_xxx'}), 'signature': '0xbe0d77590be62ec7cb0f5fd2dd5071aa6d97e8b909fd05cc80f10e6e58f0984adeeb7078f2c9a99e4a08e00102d4209900000000000000000000000000000000'})})}), '7': AttributeDict ({ 'votes ': AttributeDict({'1': AttributeDict({'epoch': 1569,'viewNumber': 22,'blockHash': '0x314adeb1ded15f49579ae2bc44d0b060d1d57905e9ddcd8da8ad1628bbee5294','blockNumber': 392228,'blockatorIndex': 7,'validatorIndex': 7, 'parentQC': AttributeDict ({ 'epoch': 1569, 'viewNumber': 22, 'blockHash': '0x69ea999a1bdb006bb9b113f20047a3d3ae79433abc1749e4fa1ec4082dcb0e90', 'blockNumber': 392227, 'blockIndex': 6, 'signature': '0x50bcc710ac0182f311065dfcb4b1c8b378788bcfe53217d6f5b29e3178508bec5557eaf7e9d360930c69c43a091e5f1800000000000000000000000000000000', 'validatorSet' :'_xxx'}),'signature': '0x7305573c2655de2537e744ef1411ea55e4 50f8879a19274ede2455f40975f59c1b9df25d3e311464fb5cbd2398fcd48600000000000000000000000000000000')))))))))))),'highestQCBlock': AttributeDict({'hash': '0x314adeb1cd8392905e9ae2dbc8d57392905e9060' 0x69ea999a1bdb006bb9b113f20047a3d3ae79433abc1749e4fa1ec4082dcb0e90','number': 392227}),'highestCommitBlock': AttributeDict({'hash': '0x92e3229453574aa2a7120e3b0dd44d3b4}number: 392dcc721304465a4) +220855883097298041197912187592864814478435487109452369765200775161577471 + +``` + +##### (8) platon.getStorageAt() + + Return the contents of the specified location of an address + + transfer: + + ``` + platon.getStorageAt(address, position [, defaultBlock]) + ``` + + parameter: + +- `address`: String-the address to be read. +- `position`: Number-index number in storage. +- `defaultBlock`: Number|String-Optional, use this parameter to override the platon.defaultBlock attribute value. + + +return value: + +An AttributeDict object whose parsed value is the content of the specified location in the storage. + +##### (9) platon.getCode + + Returns the code at the specified address. + + transfer: + + ``` + platon.getCode(address [, defaultBlock]) + ``` + + parameter: + +- `address`: String-the address of the code to be read. +- `defaultBlock`: Number|String-Optional, use this parameter to override the platon.defaultBlock attribute value. + + +return value: + +An AttributeDict object whose parsed value is the code string at the specified address. + + + +##### (10) platon.getBlock() + + Returns the block corresponding to the specified block number or block hash. + + transfer: + + ``` + platon.getBlock(blockHashOrBlockNumber [, returnTransactionObjects]) + ``` + + parameter: + +- `blockHashOrBlockNumber`: String|Number-Block number or block hash value, or use the following string: "genesis", "latest" or "pending". +- `returnTransactionObjects`: Boolean-Optional, the default value is false. When set to true, all transaction details will be included in the return block, otherwise only the transaction hash will be returned. + + +return value: + +An AttributeDict object whose parsed value is a block object that meets the search conditions and has the following fields: + +- number-Number: block number, the block in pending state is null. + +- hash 32 Bytes-String: block hash, the block in pending state is null. + +- parentHash 32 Bytes-String: parent block hash. + +- nonce 8 Bytes-String: The hash of the generated proof-of-work, the pending block is null. + +- sha3Uncles 32 Bytes-String: SHA3 value of the uncle data in the block. + +- logsBloom 256 Bytes-String: The bloom filter of the log in the block, and the block in the pending state is null. + +- transactionsRoot 32 Bytes-String: the root node of the transaction tree in the block. + +- stateRoot 32 Bytes-String: The root node of the final state tree in the block. + +- miner-String: The address of the miner receiving the reward. + +- difficulty-String: difficulty value of the block. + +- totalDifficulty-String: The total difficulty value of the whole chain up to the block. + +- extraData-String: Block "extra data" field. + +- size-Number: block size in bytes. + +- gasLimit-Number: The maximum gas value allowed in the block. + +- gasUsed-Number: The total amount of gas used by all transactions in the block. + +- timestamp-Number: the unix timestamp of the block. + +- transactions-Array: transaction object array, or 32-byte transaction hash value, depending on the setting of returnTransactionObjects. + +- uncles-Array: Uncle block hash value array. + + ##### (11) platon.getBlockTransactionCount() + + The method returns the number of transactions in the specified block. + + transfer: + + ``` + platon.getBlockTransactionCount(blockHashOrBlockNumber) + ``` + + parameter: + +- `blockHashOrBlockNumber`: String|Number-Block number or hash value of the block, or use the following string: "genesis", "latest" or "pending" to specify the block + + +return value: + +An AttributeDict object whose parsed value is the number of transactions in the specified block, of type Number. + + + +##### (12) platon.getTransaction() + + Returns the transaction object with the specified hash value. + + transfer: + + ``` +platon.getTransaction(transactionHash) + ``` + + parameter: + +- `transactionHash`: String-the hash value of the transaction + +​ + + return value: + + An AttributeDict object whose parsed value is a transaction object with a given hash value. Refer to platon.waitForTransactionReceipt for the specific content description of this object. + + + +##### (13) platon.getRawTransaction() + + Returns the HexBytes value of the transaction object with the specified hash value. + + transfer: + + ``` + platon.getRawTransaction(transactionHash) + ``` + + parameter: + +- `transactionHash`: String-the hash value of the transaction + + return value: + + An object of HexBytes values. + + + +##### (14) platon.getTransactionFromBlock() + + Returns the transaction object of the specified index number in the specified block. + + transfer: + + ``` + getTransactionFromBlock(hashStringOrNumber, indexNumber) + ``` + + parameter: + +- `hashStringOrNumber`: String-the block number or the hash value of the block, or use the following string: "genesis, "latest" or "pending" to specify the block. +- `indexNumber`: Number-transaction index position. + + return value: + + An AttributeDict object whose parsed value is a transaction object. Refer to platon.getTransaction() for the specific content description of the object. + + + +##### (15) platon.getTransactionByBlock() + + Returns the transaction object of the specified index number in the specified block. + + transfer: + + ``` + platon.getTransactionByBlock(hashStringOrNumber, indexNumber) + ``` + + parameter: + +- `hashStringOrNumber`: Number |String-the block number or the hash value of the block, or use the following string: "genesis, "latest" or "pending" to specify the block. +- `indexNumber`: Number-transaction index position. + + return value: + + An AttributeDict object whose parsed value is a transaction object. Refer to platon.getTransaction() for the specific content description of the object. + +#### **5** Send transaction api on chain: + +##### (1) sendTransaction(transactionObject) + + Submit a transaction to the platon chain (transaction that has been signed by the node and has not yet been submitted) + + parameter: + +- `transactionObject`: Object-The transaction object to be sent, including the following fields: + - from-String|Number: The account address of the transaction sender. If this field is not set, the platon.defaultAccount attribute value is used. Can be set as an address or the index number in the local wallet platon.accounts.wallet. + - to-String: Optional, the destination address of the message, this field is null for contract creation transactions. + - value-Number|String|BN|BigNumber: (optional) The value transferred for the transaction in VON, also the endowment if it’s a contract-creation transaction. + - gas-Number: optional, default value: to be determined, the total amount of gas used for transactions, unused gas will be refunded. + - gasPrice-Number|String|BN|BigNumber: Optional, the gas price of the transaction, the unit is VON, the default value is platon.gasPrice attribute value. + - data-String: Optional, it can be an ABI string containing contract method data, or the initialization code in the contract creation transaction. + - nonce-Number: Optional, use this field to cover pending transactions that use the same nonce value. + + return value: + + The return value of the `platon.sendTransaction()` method is a 32-byte transaction hash value. + + + +##### (2) waitForTransactionReceipt(transaction_hash, timeout) + + Return the receipt object of the specified transaction within the specified time. + + parameter: + +- `transaction_hash`: String-the hash value of the transaction. +- `timeout`: Number- Optional waiting time length, in seconds. The default is 120. + + return value: + + An AttributeDict object whose parsed value is the receipt object of the transaction or null. The receipt object has the following fields: + +- `blockHash` 32 Bytes-String: The hash value of the exchange in the block. +- `blockNumber`-Number: The number of the exchange in the block. +- `transactionHash` 32 Bytes-String: hash value of the transaction. +- `transactionIndex`-Number: The index position of the transaction in the block. +- `from`-String: The address of the transaction sender. +- `to`-String: The address of the recipient of the transaction. For the transaction that created the contract, the value is null. +- `contractAddress`-String: For the transaction that creates a contract, the value is the address of the created contract, otherwise it is null. +- `cumulativeGasUsed`-Number: The cumulative total gas usage of the block where the transaction is executed. +- `gasUsed`- Number: the total amount of gas for this transaction. +- `logs`-Array: The array of log objects generated by the transaction. + + + +Examples of how to use sendTransaction and waitForTransactionReceipt are as follows: + +```python # sendtransaction -to = '0xC1f330B214668beAc2E6418Dd651B09C759a4Bf5' -w3.personal.unlockAccount(address, "password", 60) +to ='lax1qqqjkfwu854vf3ze2dpy5gctmxy3gdgzsngj66' +w3.personal.unlockAccount(address, "password", 999999) data = { "from": address, "to": to, "value": 0x10909, + "gas": 1000000, + "gasPrice": 1000000000, } transaction_hex = HexBytes(platon.sendTransaction(data)).hex() result = platon.waitForTransactionReceipt(transaction_hex) print(result) + +#Output +AttributeDict(('blockHash': HexBytes('0x7bfe17689560c773b1cade579f1bd2cf85aeea9f75177e0e06bcdb4aeebd31a8'),'blockNumber': 385507,'contractAddress': None,'cumulativeGaswUsedjj25 [], 'logsBloom': HexBytes ( '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'), 'status': 1, 'to': 'lax1qqqjkfwu854vf3ze2dpy5gctmxy3gdgzsngj66', 'transactionHash': HexBytes ( '0x377fcd0dfb5e294041fe4274175ed7fce253973fac7abf4e4ff808b5099a454c'), 'transactionIndex': 0}) ``` + +##### (3) platon.getTransactionReceipt() + + Returns the receipt object of the specified transaction. + If the transaction is pending, it returns null. + + transfer: + + ``` + platon.getTransactionReceipt(hash) + ``` + + parameter: + +- `hash`: String-the hash value of the transaction + + return value: + + An AttributeDict object whose parsed value is the receipt object of the transaction or null. Refer to platon.waitForTransactionReceipt for the specific content description of this object. + +##### (4) platon.getTransactionCount() + + Returns the number of transactions issued by the specified address. + + transfer: + + ``` + platon.getTransactionCount(address [, defaultBlock]) + ``` + + parameter: + +- `address`: String-the address of the account to be queried. +- `defaultBlock`: Number|String-Optional, set this parameter to override the platon.defaultBlock property value. + + return value: + + An AttributeDict object whose resolved value is the number of transactions issued by the specified address. + +##### (6) platon.sendRawTransaction() + + Submit a signed serialized transaction to the platon chain + + ``` +platon.sendRawTransaction(signTransaction, private-key) + ``` + + parameter: + +- `signTransaction`: Object-The signed transaction object to be sent, including the following fields: + + - from-String|Number: The account address of the transaction sender. If this field is not set, the platon.defaultAccount attribute value is used. Can be set as an address or the index number in the local wallet platon.accounts.wallet . + - to-String: Optional, the destination address of the message, this field is null for contract creation transactions . + - value-Number|String|BN|BigNumber: (optional) The value transferred for the transaction in VON, also the endowment if it’s a contract-creation transaction. + + - gas-Number: optional, default value: to be determined, the total amount of gas used for transactions, unused gas will be refunded. + + - gasPrice-Number|String|BN|BigNumber: Optional, the gas price of the transaction, in VON, the default value is platon.gasPrice property value. + + - data-String: Optional, it can be an ABI string containing contract method data, or the initialization code in the contract creation transaction. + + - nonce-Number: Optional, use this field to cover pending transactions that use the same nonce value. + +- private-key: the private key used for signing. + + return value: + + The return value is HexBytes containing the 32-byte transaction hash value. + + + +##### (7) platon.replaceTransaction() + + Send a new transaction new_transaction to replace the original transaction transaction_hash (pending state). + + transfer: + + ```python + platon.replaceTransaction`(transaction_hash,new_transaction) + ``` + + parameter: + +- transaction_hash-string: The hash value of the transaction in the pending state. + +- new_transaction-dict: transaction object, including fields consistent with transactionObject in sendTransaction. + + return value: + + The hash value of new_transaction. + + + +##### (8) platon.generateGasPrice() + + Use the selected gas price strategy to calculate a gas price + + transfer: + + ``` + platon.generateGasPrice(gas_price_strategy) + ``` + + Return value: + + The gas price value in wei + + + +##### (9) platon.setGasPriceStrategy() + + Set the selected gas price strategy + + transfer: + + ``` + platon.setGasPriceStrategy(gas_price_strategy) + ``` + + parameter: + +- gas_price_strategy: (web3, transaction_params), must be a signature method. + + return: + +- The gas price value in wei + +##### (10) platon.modifyTransaction() + + Send new parameters to modify the pending transaction + + transfer: + + ```python + platon.modifyTransaction(transaction_hash, **transaction_params) + ``` + + parameter: + +- transaction_hash -string: The hash value of the transaction in the pending state. +- transaction_params: keyword statements corresponding to the parameters of transaction_hash. If value=1000, change the value value in the original transaction to 1000. + + return: + + The hash value of the revised transaction . + +##### (11) platon.sign() + + The method uses the specified account to sign the data, and the account must be unlocked first. + + transfer: + + ``` + platon.sign(dataToSign, address) + ``` + + parameter: + +- `dataToSign`: String-The data to be signed. For the string, it will first use the utils.utf8ToHex() method to convert it to hexadecimal. +- `address`: String|Number-The account address used for signing. Or the address or its serial number in the local wallet platon.accounts.wallet + + return value: + + The signature result string. + +##### (12) platon.estimateGas() + + Estimate the gas usage of the transaction by executing a message call. + + transfer: + + ``` + platon.estimateGas(callObject) + ``` + + parameter: + +- `callObject`: Object-transaction object, its from attribute is optional + + return value: + + The amount of gas used for simulation calls. + + + +#### 6 Other api + +##### (1) platon.filter + + Generate a new filter, according to the different parameters, generate different types of filters + + transfer: + + ``` + platon.filter(params) + ``` + + parameter: + +- params + - 'latest', create a filter in the node to be notified when a new block is generated. To check whether the status has changed. + - 'pending', create a filter in the node to notify when a pending transaction occurs. To check whether the status has changed. + - Dictionary data, create a filter to notify when the client receives a matching whisper message. + + +​ + + ```python + >>> platon.filter('latest') + + >>> platon.filter('pending') + + >>> platon.filter({'fromBlock': 1000000,'toBlock': 1000100,'address':'lax1yjjzvjph3tw4h2quw6mse25y492xy7fzwdtqja'}) + + ``` + + + +##### (2) platon.getFilterChanges() + + Polling the specified filter and returning the newly generated log array since the last poll. + + transfer: + + ``` + platon.getFilterChanges(filter_id) + ``` + + parameter: + +- filter_id: filter_id of the specified filter. + + + + Example: + + ```python + >>> filt=platon.filter('latest') + >>>platon.getFilterChanges(filt.filter_id) + [HexBytes ( '0x59c4cb22c15ed83279e288ccc94980162e7cc7c1ff9c6b4fb6d9584308727b46'), HexBytes ( '0xb205babee34ba218816d1a32e995a4c8f4ccf95d3315c6a259955f1598ed5e4d'), HexBytes ( '0xb491ef8c0cc55cc1b70e9af766ada828a5a96bbb41f6aa26b87c98dbf09ac762'), HexBytes ( '0x455ae7bee30a02210fc17ade1cec3d783ce9614f81149ea650efc27a39e495a5'), HexBytes ( '0xd8c8f327e6613dc9a638c4ad2e2e37ce511ea80d374fea91d961d3fb55ed0e3a'), HexBytes ( '0x92e85ab7340ae8f6c0da6d5fa5cab5a3ae61f7d69158b612b7caf470de4e0958'), HexBytes ( '0x612d8f92bdec45052576b62a03a5c6d5b219ad5eecf088163cc629efc506a4dc'), HexBytes ( '0xd433b552bf421ee416c31d7c9162d8f08a7580d906538a3e0156f504161c6889'), HexBytes ( '0x5f9d64faf699f6e688989bcb6133c001cd5d24315c22375c5f1935909ee5b31e'), HexBytes ( '0x70b10afd243a5f6c0992bdb80bf75974cf3b8b78c254c054e6824621d2a55a33'), HexBytes ( '0x5f631fc85544b8e04504a71e99a67f8020596221ecfbefefde98fb44f4c3cf65'), HexBytes ( '0x6012ab1a562e818e4ca3e6e1b719e21cd900ac1daaf26c87f983c75e2cddd9ab'), HexBytes ( '0x2cc3d3e257dd9af953968a75a65 3cd9cfb0f6157aca1ba3089ebfe65d32c3543 '), HexBytes (' 0x3696eea818d042c0cae606093262268ec36aa0f23904101cdb25d7c1595bbeae '), HexBytes (' 0x4825078dc7cfb3f065acd1d300a3c111b51445488862bebd44801af6272d36cd '), HexBytes (' 0x3df27825fa9e89b91f83df4769ae6477bf060c5ff078e8f1b05edee136368f4f '), HexBytes (' 0x9e7bdf9ef1ce7e66b3615fa882fa420dfefe3c93efb433ff824d6c7fa73e08ca '), HexBytes (' 0x0d8f9a5a5cd4e95a57f6183c94826861a259e631d0127f4b0f268e104bc3c92e '), HexBytes (' 0xa310dbde88c8721fad793c7f2cb594b2bec108482990d2c56e3dc427f09d21af '), HexBytes (' 0x2e944efb7d3cf8bf9c354a02b34cbc262a044b5e2fd484daad8f7b81663e4cb0 '), HexBytes (' 0x19c72519b3fcf6d74bcef061f0f6b12eabbf9cb13d482db38b94e1fb86dd4b25 '), HexBytes (' 0x435956b99ce8d0777d5d7e19e87d3277eccd757a56da6d100fb7b536ff417ded '), HexBytes (' 0xe291f184a80c1c65a44198ed8c2d35d5ef98f65dada59a0e1fc28aa21bbe69ea '), HexBytes (' 0x21b088023a06a9c85b16fcdd6bab07697905241a139d8a3efc0e0e7a9d7a00a0 '), HexBytes (' 0x6bf9d36ec461b66191ec8f026bec905a0f46a83707960987bb559d13a5186082 '), HexBytes ( '0x85aaf311fe7c2c80340f334b7f52bb0c4282341559e056e852e92135bc04e917'), HexBytes ( '0x033e7b67bd5f509de11e38cc142a70def69048f5d214ac5d15e83102a93a011d'), HexBytes ( '0x02d55d41e12ea9edd986da149e42f302719ad769eb4496872271c063a6ab3bcd'), HexBytes ( '0x3914a9fcf5be7aca72a50d59a1b7cdb18f96540dafba0de84f8297228cb9159a'), HexBytes ( '0xc45b0552883b21012431f9e76ccd5ce9e3c8550ecbbb223a1d69ebc6a354b34d'), HexBytes ( '0xbfa4324da6aafa66907586c535a2207a082063670fff102f8df19ab1a4e665d0')] + + ``` + + + +##### (3) platon.getFilterLogs() + + Poll the specified filter and return the corresponding log array + + transfer: + + ``` + platon.getFilterLogs(filter_id) + ``` + + parameter: + +- filter_id: filter_id of the specified filter + + + +##### (4) platon.uninstallFilter() + + Uninstall the specified filter and return the bool value of success or failure + + transfer: + + ``` + platon.getFilterLogs(filter_id) + ``` + +parameter: +- filter_id: filter_id of the specified filter + +Example: + +```python +>>> platon.uninstallFilter(filt.filter_id) +True +``` + + + +##### (5) platon.getLogs() + + Return the history log according to the specified options. + + transfer: + + ``` + platon.getLogs(options) + ``` + + parameter: + +- `options`: Object-filter object, including the following fields: +- fromBlock-Number|String: The number of the earliest block ("latest" may be given to mean the most recent and "pending" currently mining, block). By default "latest". +- toBlock-Number|String: The number of the latest block ("latest" may be given to mean the most recent and "pending" currently mining, block). By default "latest". +- address-String|Array: An address or a list of addresses to only get logs from particular account(s). +- topics-Array: An array of values ​​which must each appear in the log entries. The order is important, if you want to leave topics out use null, eg [null, '0x12...']. You can also pass an array for each topic with options for that topic eg [null, ['option1','option2']] + + return value: + + An AttributeDict object whose parsed value is an array of log objects. + + The event object structure in the array is as follows: + +- address-String: The source address of the event + +- data-String: Contains unindexed log parameters + +- topics-Array: an array containing up to 4 32-byte topics, topics 1-3 contain log index parameters + +- logIndex-Number: The index position of the event in the block + +- transactionIndex-Number: The index position of the transaction containing the event + +- transactionHash 32 Bytes-String: The hash value of the transaction containing the event + +- blockHash 32 Bytes-String: The hash value of the block containing the event, or null if it is in the pending state + +- blockNumber-Number: The block number containing the event, this field is null when it is in the pending state + + + +##### (6) functions() + + Entrance to call contract function + + transfer: + + ```python + myContract.functions.myMethod([param1[, param2[, ...]]]).transact(options) + ``` + +- parameter: + - `options`-Object: Options, including the following fields: + - `from`-String (optional): The address the call “transaction” should be made from. + - gasPrice-String (optional): The gas price in VON to use for this call “transaction”. + - gas-Number (optional): The maximum gas provided for this call “transaction” (gas limit). + + +​ + +##### (7) call() + + Call the method of the contract and execute the method directly in the contract without sending any transactions. Therefore, the state of the contract will not be changed. + + transfer: + + ``` + myContract.functions.myMethod([param1[, param2[, ...]]]).call() + ``` + + parameter: + +- [param1[, param2[, ...]]]: parameters entered according to the data type defined in myMethod + + return value: + + The parsed value is the return value of the contract method, the Mixed type. If the contract method returns multiple values, the resolved value is an object. + + ```python + tx_hash1 = payable.functions.setInt64(-9223372036854775808).transact( + { + 'from':from_address, + 'gas': 1500000, + } + ) + print(platon.waitForTransactionReceipt(tx_hash1)) + print('get: {}'.format( + payable.functions.getInt64().call() + )) + + #Output + get: -9223372036854775808 + ``` + + + +##### (8) events + + Subscribe to the specified contract event. + + transfer: + + ``` + myContract.events.MyEvent([options]) + ``` + +- parameter: + - options-Object: Optional, options for deployment, including the following fields: + - filter-Object: Optional, filter events by index parameter. For example, {filter: {myNumber: [12,13]}} means all events where "myNumber" is 12 or 13 + - fromBlock-Number: Optional, only listen to events that occur in the block with the number specified by this option + - topics-Array: Optional, used to manually set topics for event filters. If the filter attribute and event signature have been set, then (topic[0]) will not be set automatically + + return value: + + EventEmitter: Event generator, declares the following events: + +- "data" returns Object: Triggered when a new event is received, the parameter is the event object. +- "changed" returns Object: Triggered when the event is removed from the blockchain, the event object will be added with an additional property "removed: true". + +- "error" returns Object: Triggered when an error occurs. + + The returned event object structure is as follows: + +- event-String: event name. +- signature-String|Null: Event signature, if it is an anonymous event, it will be null. +- address-String: Event source address. +- returnValues-Object: Event return value, for example {myVar: 1, myVar2: '0x234...'}. +- logIndex-Number: The index position of the event in the block. +- transactionIndex-Number: the index position of the event in the transaction. +- transactionHash 32 Bytes-String: The hash value of the transaction where the event is located. +- blockHash 32 Bytes-String: The hash value of the block where the event is located, the value of the pending block is null. +- blockNumber-Number: The number of the block where the event is located, the value of the pending block is null. +- raw.data-String: This field contains unindexed log parameters. +- raw.topics-Array: Up to 4 32-byte long topic string arrays can be stored. Topics 1-3 include index parameters for events. + + Sample code: + + ```python + greeter = platon.contract(address=tx_receipt.contractAddress, abi=abi) + + tx_hash = greeter.functions.setVar(100).transact( + { + 'from':from_address, + 'gas': 1500000, + } + ) + + tx_receipt = platon.waitForTransactionReceipt(tx_hash) + print(tx_receipt) + + topic_param = greeter.events.MyEvent().processReceipt(tx_receipt) + print(topic_param) + + #Output: + AttributeDict({'blockHash': HexBytes('0x78fb61da83dae555c8a8a87fc3296f466afeb7f90e9a3b0ac5689e8b34435174'),'blockNumber': 2014683,'contractAddress': None,'cumulativeqqdUsed': 43148x' from [AttributeDict({'address':'lax1vc6phdxhdkmztpznv5ueduw6cae3swe40whlsn','topics': [HexBytes('0x6c2b4666ba8da5a95717621d879a77deactionf3d816709b9cbe9f'b8f3d816709b9cbe9f059'b8f0000000000000'Number00000000'00000064',0000000000000)',00000000000000 HexBytes ( '0xe36b5d2b679d5635ab6dd2b620caa50a476fa84bd93bf7b6c8de807f3a9da483'), 'transactionIndex': 0, 'blockHash': HexBytes ( '0x78fb61da83dae555c8a8a87fc3296f466afeb7f90e9a3b0ac5689e8b34435174'), 'logIndex': 0, 'removed': False})], 'logsBloom': HexBytes ( '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000020080000000000000000000000000000000000000000000000000000 000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000004000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000008000000000000000 '),' status': 1, 'to': 'lax1vc6phdxhdkmztpznv5ueduw6cae3swe40whlsn', 'transactionHash': HexBytes ( '0xe36b5d2b679d5635ab6dd2b620caa50a476fa84bd93bf7b6c8de807f3a9da483'), 'transactionIndex': 0}) + (AttributeDict({'args': AttributeDict({'_var': 100}),'event':'MyEvent','logIndex': 0,'transactionIndex': 0,'transactionHash': HexBytes('0xe36b5d2b679d5635ab6dd2b620caa483807f) 'address':'lax1vc6phdxhdkmztpznv5ueduw6cae3swe40whlsn','blockHash': HexBytes('0x78fb61da83dae555c8a8a87fc3296f466afeb7f90e9a3b0ac5689e8)34435174'), '2014683 + + ``` + + #### 7. Get hrp + +``` +w3 = Web3(HTTPProvider("http://localhost:6789"),chain_id = 100) +platon = PlatON(w3) +print(platon.getAddressHrp) +``` + + + +### Third part: the contract + +#### 1. Contract introduction + +The PlatON blockchain supports smart contracts (evm) created using the solidity language, and it also supports WebAssembly (WASM) to execute smart contracts written by users. Among them, WASM is a binary instruction set designed for stack virtual machines. WASM is designed to be available for platform compilation targets like C/C++/Rust and other high-level languages. The original design purpose is to solve the performance problem of JavaScript. WASM is a Web standard that is being promoted by W3C and is supported by browser vendors such as Google, Microsoft, and Mozilla. + +For details on the introduction, creation, and compilation of evm and wasm contracts, please refer to [Platon Smart Contract](https://devdocs.platon.network/docs/zh-CN/WASM_Smart_Contract/) + + + +#### **2**、 Contract compilation + +The python sdk currently supports bin and abi formed after the evm and wasm contracts are compiled as contract data to interact with the PlatON blockchain. + +**(1)** The evm contract (created in solidity language) can be compiled, deployed, and invoked using platon-truffle. For details, please refer to [solidity compiler](https://github.com/PlatONnetwork/solidity) and [platon-truffle](https://platon-truffle.readthedocs.io/en/v0.13.1/getting-started/ installation.html) +**(2)** The wasm contract (created in C/C++/Rust and other languages) can be compiled, deployed, and invoked using PlatON-CDT or platon-truffle. For details, please refer to [PlatON-CDT Compiler](https://github.com/PlatONnetwork/PlatON-CDT/tree/feature/wasm) + + + +#### 3. SDK calls to evm contract + +##### (1) Use platon-truffle to compile the evm contract locally + + Obtain bin and abi. Take the Helloworld contract as an example. + + After using platon-truffle to compile Helloworld.sol, get the abi and bytecode (bin) in the generated build/contracts/HelloWorld.json. + +##### (2) Deploy Helloworld contract through python SDK + + First connect to the node via Web3 + + from_address is the account address on the node + + bytecode and abi are the bin and abi after the evm contract is compiled + + ```python + from hexbytes import HexBytes + from client_sdk_python import Web3, HTTPProvider + from client_sdk_python.eth import PlatON + from platon_keys.utils import bech32,address + from client_sdk_python.packages.eth_utils import to_checksum_address + + true = True + false = False + + w3 = Web3(HTTPProvider("http://10.1.1.5:6789"),chain_id = 100) + platon = PlatON(w3) + print(w3.isConnected()) + + from_address = "lax1yjjzvjph3tw4h2quw6mse25y492xy7fzwdtqja" + + bytecode = '608060405234801561001057600080fd5b50610c28806100206000396000f3fe608060405234801561001057600080fd5b50600436106101375760003560e01c806357609889116100b85780638e418fdb1161007c5780638e418fdb146104b2578063a64be0d5146104d0578063b4feac7c146104ee578063b87df0141461050c578063c0e641fc1461052a578063da193c1f1461054857610137565b80635760988914610352578063687615d71461037057806371ee52021461038e57806378aa6155146104115780637e6b0f571461042f57610137565b806344e24ce0116100ff57806344e24ce01461029c57806347808fc3146102ca5780634b8016b9146102f8578063508242dc1461031657806356230cca1461033457610137565b80631f9c9f3c1461013c578063275ec9761461015a57806335432d3114610178578063383d49e5146101fb5780633f9dbcf914610219575b600080fd5b610144610566565b6040518082815260200191505060405180910390f35b61016261056c565b6040518082815260200191505060405180910390f35b6101806105ca565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101c05780820151818401526020810190506101a5565b50505050905090810190601f16 80156101ed5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610203610668565b6040518082815260200191505060405180910390f35b61022161066e565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610261578082015181840152602081019050610246565b50505050905090810190601f16801561028e5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6102c8600480360360208110156102b257600080fd5b810190808035906020019092919050505061070c565b005b6102f6600480360360208110156102e057600080fd5b8101908080359060200190929190505050610811565b005b6103006108a4565b6040518082815260200191505060405180910390f35b61031e6108aa565b6040518082815260200191505060405180910390f35b61033c6108b0565b6040518082815260200191505060405180910390f35b61035a610907565b6040518082815260200191505060405180910390f35b610378610911565b6040518082815260200191505060405180910390f35b610396610917565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156103 d65780820151818401526020810190506103bb565b50505050905090810190601f1680156104035780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6104196109b9565b6040518082815260200191505060405180910390f35b6104376109c3565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561047757808201518184015260208101905061045c565b50505050905090810190601f1680156104a45780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6104ba610a65565b6040518082815260200191505060405180910390f35b6104d8610a9b565b6040518082815260200191505060405180910390f35b6104f6610af2565b6040518082815260200191505060405180910390f35b610514610b30565b6040518082815260200191505060405180910390f35b610532610b3a565b6040518082815260200191505060405180910390f35b610550610b44565b6040518082815260200191505060405180910390f35b60025481565b6000806005819055506000600190505b600a8110156105c05760006005828161059157fe5b0614156105a3576005549150506105c7565b806005600082825401925050819055508080 60010191505061057c565b5060055490505b90565b60008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156106605780601f1061063557610100808354040283529160200191610660565b820191906000526020600020905b81548152906001019060200180831161064357829003601f168201915b505050505081565b60035481565b60068054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156107045780601f106106d957610100808354040283529160200191610704565b820191906000526020600020905b8154815290600101906020018083116106e757829003601f168201915b505050505081565b6014811015610766576040518060400160405280601381526020017f796f7520617265206120796f756e67206d616e0000000000000000000000000081525060009080519060200190610760929190610b4e565b5061080e565b603c8110156107c0576040518060400160405280601481526020017f796f75206172652061206d6964646c65206d616e00000000000000000000000081525060009080 5190602001906107ba929190610b4e565b5061080d565b6040518060400160405280601181526020017f796f75206172652061206f6c64206d616e0000000000000000000000000000008152506000908051906020019061080b929190610b4e565b505b5b50565b60148113610854576040518060400160405280600c81526020017f6d6f7265207468616e203230000000000000000000000000000000000000000081525061088b565b6040518060400160405280600c81526020017f6c657373207468616e20323000000000000000000000000000000000000000008152505b600690805190602001906108a0929190610b4e565b5050565b60045481565b60015481565b60008060048190555060008090505b600a8110156108fe576000600282816108d457fe5b0614156108e0576108f1565b806004600082825401925050819055505b80806001019150506108bf565b50600454905090565b6000600454905090565b60055481565b606060068054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156109af5780601f10610984576101008083540402835291602001916109af565b820191906000526020600020905b8154815290600101906020 0180831161099257829003601f168201915b5050505050905090565b6000600554905090565b606060008054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610a5b5780601f10610a3057610100808354040283529160200191610a5b565b820191906000526020600020905b815481529060010190602001808311610a3e57829003601f168201915b5050505050905090565b60008060018190555060008090505b80600160008282540192505081905550806001019050600a8110610a745760015491505090565b6000806003819055506000600190505b600a811015610ae957600060028281610ac057fe5b061415610acc57610ae9565b806003600082825401925050819055508080600101915050610aab565b50600354905090565b60008060028190555060008090505b600a811015610b2757806002600082825401925050819055508080600101915050610b01565b50600254905090565b6000600254905090565b6000600354905090565b6000600154905090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10610b8f57805160ff1916838001178555610bbd565b8280 0160010185558215610bbd579182015b82811115610bbc578251825591602001919060010190610ba1565b5b509050610bca9190610bce565b5090565b610bf091905b80821115610bec576000816000905550600101610bd4565b5090565b9056fea265627a7a7231582003a28b4281af2c524edc05a0c071a68e9f08b99e0a7e70b37dcc181d06a48e6c64736f6c634300050d0032 ' + + abi = [{"constant":false,"inputs":[],"name":"doWhileControl","outputs":[{"internalType":"uint256","name":"","type": "uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"doWhileControlResult" ,"outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type": "function"},{"constant":false,"inputs":[],"name":"forBreakControl","outputs":[{"internalType":"uint256","name":"","type ":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":" forBreakControlResult","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type ":"function"},{"constant":false,"inputs":[],"name":"forContinueControl","outputs":[{"internalType":"uint256","name":"", "type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name" :"forContinueControlResu lt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type ":"function"},{"constant":false,"inputs":[],"name":"forControl","outputs":[{"internalType":"uint256","name":"", "type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name" :"forControlResult","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view", "type":"function"},{"constant":false,"inputs":[],"name":"forReturnControl","outputs":[{"internalType":"uint256","name":" ","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[]," name":"forReturnControlResult","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view ","type":"function"},{"constant":false,"inputs":[{"internalType":"int256","name":"age","type":"int256"}], "name":"forThreeControlControl","outputs":[],"pa yable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"forThreeControlControlResult","outputs":[{ "internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{" constant":true,"inputs":[],"name":"getForBreakControlResult","outputs":[{"internalType":"uint256","name":"","type":"uint256"}] ,"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getForContinueControlResult","outputs": [{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}, {"constant":true,"inputs":[],"name":"getForControlResult","outputs":[{"internalType":"uint256","name":"","type":"uint256" }],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getForReturnControlResult","outputs ":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"fu nction"},{"constant":true,"inputs":[],"name":"getForThreeControlControlResult","outputs":[{"internalType":"string","name":"","type" :"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getIfControlResult ","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type" :"function"},{"constant":true,"inputs":[],"name":"getdoWhileResult","outputs":[{"internalType":"uint256","name":""," type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":" uint256","name":"age","type":"uint256"}],"name":"ifControl","outputs":[],"payable":false,"stateMutability":"nonpayable", "type":"function"},{"constant":true,"inputs":[],"name":"ifControlResult","outputs":[{"internalType":"string","name":" ","type":"string"}],"payable":false,"stateMutability":"view","type":"function"}] + + #Output + True + lax1yjjzvjph3tw4h2quw6mse25y492xy7fzwdtqja + ``` + + ​ Then use the function contract_deploy(bytecode, fromAddress) to deploy the evm contract on the nodes of the PlatON blockchain by sending transactions, and return the transaction hash transactionHash. + + ​ tx_receipt is the deployment receipt obtained after platon.waitForTransactionReceipt parses the transactionHash (deployment is also a transaction, and the transaction obtains the transaction receipt through platon.waitForTransactionReceipt). + + ```python + def contract_deploy(bytecode, fromAddress): + bytecode = bytecode + transactionHash = platon.sendTransaction( + { + "from": fromAddress, + "gas": 1000000, + "gasPrice": 1000000000, + "data": bytecode, + } + ) + transactionHash = HexBytes(transactionHash).hex().lower() + return transactionHash + + tx = contract_deploy(bytecode, from_address) + print(tx) + tx_receipt = platon.waitForTransactionReceipt(tx) + print(tx_receipt) + contractAddress = tx_receipt.contractAddress + print(contractAddress) + + ``` + + platon.sendTransaction (parameter) + +- parameter: + + - `from` The address of the account that sent the transaction. + + - `data` The data sent to the chain. + + - `gas` The amount of gas traded. + + - `gasPrice` fuel price. + + + Need to write a reasonable value + + + + If the deployment is successful, the output results are as follows + + ```python + + #Output + 0x143efc88f581c4356156519cde51064222ec5a42fcb4d83400a8b11893a95074 + AttributeDict ({ 'blockHash': HexBytes ( '0xf73097d8e7b2cc385910a4af3a4dbc7588774bad3f2b6589052503b649af1525'), 'blockNumber': 305798, 'contractAddress':' lax1ws7m2tqr55h8xs7e3jg5svlyu0lk9ktpx03cke ',' cumulativeGasUsed ': 319449,' from ':' lax1yjjzvjph3tw4h2quw6mse25y492xy7fzwdtqja ',' gasUsed ': 319449,' logs ': [],' logsBloom ': HexBytes (' 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 '),' status': 1, 'to': None, 'transactionHash': HexBytes ( '0x143efc88f581c4356156519cde51064222ec5a42fcb4d83400a8b11893a95074'), 'transactionIndex': 0}) + lax1ws7m2tqr55h8xs7e3jg5svlyu0lk9ktpx03cke + ``` + + - among them + + - The first line of data is the transaction result of platon.sendTransaction in the function contract_deploy. + - The second line of data is the transaction receipt obtained by platon.waitForTransactionReceipt. + - The third line is the contract address where the contract is successfully deployed. + + + +##### (3) Call the Helloworld contract (transaction sending) + + Based on the successful deployment of the previous contract, the transaction is sent + + First define a function SendTxn(txn) + + Contains: Sign transaction platon.account.signTransaction (signature with private key) + + ​ Send transaction platon.sendRawTransaction + + ​ Get transaction receipt platon.waitForTransactionReceipt + + ```python + send_privatekey = "b7a7372e78160f71a1a75e03c4aa72705806a05cf14ef39c87fdee93d108588c" + def SendTxn(txn): + signed_txn = platon.account.signTransaction(txn,private_key=send_privatekey) + res = platon.sendRawTransaction(signed_txn.rawTransaction).hex() + txn_receipt = platon.waitForTransactionReceipt(res) + print(res) + return txn_receipt + + ``` + + Create a contract instance contract_instance. Because it is an evm contract, the function contract is used. If it is a wasm contract, it corresponds to the function wasmcontract. + + Call method ifControl through functions, input parameter 20, and send transaction information through buildTransaction + + ```python + contract_instance = platon.contract(address=contractAddress, abi=abi) + + txn = contract_instance.functions.ifControl(20).buildTransaction( + { + 'chainId': 200, + 'nonce':platon.getTransactionCount(from_address), + 'gas': 2000000, + 'value':0, + 'gasPrice':1000000000, + } + ) + + print(SendTxn(txn)) + + result = contract_instance.functions.getIfControlResult().call() + print(result) + ``` + +parameter: + +- `chainId`: chain id. + +- `nonce`: serial number. + +- `gas` :fuel. +- `value`: value (starting balance of new contract account). +- `gasPrice`: fuel price. + +Need to write a reasonable value + + Call the method ifControl, and successfully pass the parameter 20 to the chain. Then get the corresponding information and data on the chain through the corresponding method getIfControlResult. + +The output is as follows: + + ``` + #Output: + 0x16c76387cdd06ab82a4beb330b36369a5cfa22b8cf6ddfff58c72aaae4a39df9 + AttributeDict(('blockHash': HexBytes('0xbb1d1c3a7abecac9910509ed3ff2ca97cebdba1e88db0b909ffd646a86d69597'),'blockNumber': 305801,'contractAddress': None,'cumulativeGaswUsedjj25382,'from [], 'logsBloom': HexBytes ( '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'), 'status': 1, 'to': 'lax1ws7m2tqr55h8xs7e3jg5svlyu0lk9ktpx03cke', 'transactionHash': HexBytes ( '0x16c76387cdd06ab82a4beb330b36369a5cfa22b8cf6ddfff58c72aaae4a39df9'), 'transactionIndex': 0}) + ``` + +- among them + + - The first line of data is the transaction result of platon.sendRawTransaction in the function SendTxn. + + - The second line of data is the method ifControl sends information to the chain, the result of the transaction. + + - The third line method getIfControlResult gets the information on the chain and the result of the transaction. + + + +##### (4) Event call of evm contract + + The evm contract can monitor and log the detailed information of related transactions through events. + + Take the evmevent contract as an example: it adds the event type MyEvent to the method setVar. + + Greeter is the successfully deployed evm contract. + + First call setVar through functions and pass the parameters to the chain + + Then through greeter.events.MyEvent(), call the event to output the detailed log of the transaction. + + The .events method is the event api dedicated to the contract. + + ```python + greeter = platon.contract(address=tx_receipt.contractAddress, abi=abi) + + tx_hash = greeter.functions.setVar(100).transact( + { + 'from':from_address, + 'gas': 1500000, + } + ) + + tx_receipt = platon.waitForTransactionReceipt(tx_hash) + print(tx_receipt) + + topic_param = greeter.events.MyEvent().processReceipt(tx_receipt) +print(topic_param) + ``` + + Output after successful operation: + + ```python + AttributeDict({'blockHash': HexBytes('0x78fb61da83dae555c8a8a87fc3296f466afeb7f90e9a3b0ac5689e8b34435174'),'blockNumber': 2014683,'contractAddress': None,'cumulativeqqdUsed': 43148x' from [AttributeDict({'address':'lax1vc6phdxhdkmztpznv5ueduw6cae3swe40whlsn','topics': [HexBytes('0x6c2b4666ba8da5a95717621d879a77deactionf3d816709b9cbe9f'b8f3d816709b9cbe9f059'b8f0000000000000'Number00000000'00000064',0000000000000)',00000000000000 HexBytes ( '0xe36b5d2b679d5635ab6dd2b620caa50a476fa84bd93bf7b6c8de807f3a9da483'), 'transactionIndex': 0, 'blockHash': HexBytes ( '0x78fb61da83dae555c8a8a87fc3296f466afeb7f90e9a3b0ac5689e8b34435174'), 'logIndex': 0, 'removed': False})], 'logsBloom': HexBytes ( '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000020080000000000000000000000000000000000000000000000000000 000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000004000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000008000000000000000 '),' status': 1, 'to': 'lax1vc6phdxhdkmztpznv5ueduw6cae3swe40whlsn', 'transactionHash': HexBytes ( '0xe36b5d2b679d5635ab6dd2b620caa50a476fa84bd93bf7b6c8de807f3a9da483'), 'transactionIndex': 0}) + (AttributeDict({'args': AttributeDict({'_var': 100}),'event':'MyEvent','logIndex': 0,'transactionIndex': 0,'transactionHash': HexBytes('0xe36b5d2b679d5635ab6dd2b620caa483807f) 'address':'lax1vc6phdxhdkmztpznv5ueduw6cae3swe40whlsn','blockHash': HexBytes('0x78fb61da83dae555c8a8a87fc3296f466afeb7f90e9a3b0ac5689e8)34435174'), '2014683 + + ``` + + The first line calls the function setVar, the transaction receipt after the transaction is successful. + + The second line calls the event MyEvent() to get the transaction log information. + + Among the values ​​corresponding to'args': + + '_var' is the only parameter value + + In the event of the evm contract, the basic types of data are uint, int, bool, address, bytex. + + + +#### 4. SDK calls to wasm contract: + + + +##### (1) Use PlatON-CDT to compile wasm contract locally + + Take wasmcontract.cpp as an example. After installing PlatON-CDT on this machine, enter the code in PlatON-CDT/build/bin. + + ``` + platon-cpp wasmcontract.cpp + ``` + + After successful compilation, there are two files in wasmcontract/build/contracts. + + wasmcontract.abi.json and wasmcontract.wasm, where wasmcontract.abi.json is abi data (json format), wasmcontract.wasm is bin data (binary format). + + ```python + import binascii + f = open('D:/wasmcontract.wasm','rb') + contents=f.read() + bytecode=binascii.b2a_hex(contents) + ``` + + Because what our chain recognizes is hexadecimal data, we need to use methods similar to binascii.b2a_hex to convert the binary .wasm to hexadecimal bytecode. Facilitate our identification on the chain. + +##### (2) Deploy Helloworld contract (wasm type) through python SDK + + After obtaining the bin and abi of the wasm contract, deploy on the chain through Web3. + + In the code below, bytecode is the bin data of the contract, and cabi is the abi data of the contract. + + ```python + from client_sdk_python import Web3, HTTPProvider + from client_sdk_python.eth import PlatON + true = True + false = False + + w3 = Web3(HTTPProvider("http://10.1.1.2:6789"),chain_id = 100) + platon = PlatON(w3) + print(w3.isConnected()) + from_address = "lax1uqug0zq7rcxddndleq4ux2ft3tv6dqljphydrl" + + bytecode = '0061736d01000000015c1060027f7f0060017f017f60027f7f017f60017f0060037f7f7f017f60037f7f7f0060047f7f7f7f0060000060047f7f7f7f017f60027f7e0060017f017e60037f7e7e0060037f7e7e017f60017e017f60057f7f7f7f7f006000017f02ce010903656e760c706c61746f6e5f70616e6963000703656e760b706c61746f6e5f73686133000603656e7617706c61746f6e5f6765745f696e7075745f6c656e677468000f03656e7610706c61746f6e5f6765745f696e707574000303656e7617706c61746f6e5f6765745f73746174655f6c656e677468000203656e7610706c61746f6e5f6765745f7374617465000803656e7610706c61746f6e5f7365745f7374617465000603656e760c706c61746f6e5f6576656e74000603656e760d706c61746f6e5f72657475726e000003cd01cb010700020200040000010202020302020500000e000000020001000200010002000001020600020002000200000204000002010102040506000303010400050402050500000104020503010001040c00040b01000004080304000107070704050a0a030103010101010101010d09010000000003000100020100010001010001010a0d09000100000100000201000100010001000001000100010003010001000108030100020100090001030100010100000c0b 0208000300000003030105070501010206000600000000000405017001050505030100020608017f0141908c040b073904066d656d6f72790200115f5f7761736d5f63616c6c5f63746f727300090f5f5f66756e63735f6f6e5f65786974006506696e766f6b650063090a010041010b04202124250af0b902cb01050010c7010baa0301097f230041c0016b22022400200241b908100b2104200241e8006a4102100c2103200241d8006a2004100d200241c8006a2000100d200241406b4100360200200241386a4200370300200241306a420037030020024200370328200241286a20022802582204200228025c100e20022802482205200228024c100e210620032002280228100f2003200241d8006a10102003200241c8006a1010200328020c200341106a28020047044010000b2003280204210720032802002108200241106a1011210020024180016a200110122101200241a8016a4100360200200241a0016a420037030020024198016a4200370300200242003703900120024190016a41001013200241b0016a200110121014410110132109200228029001210a200941046a10152000200a100f20004101101620024190016a200110121017220028020c200041106a28020047044010000b20082007200028020020002802041007200028020c22010440200020013602100b 200641046a1015200504402002200536024c0b200404402002200436025c0b200328020c22000440200320003602100b200241c0016a24000b910101027f20004200370200200041086a410036020020012102024003402002410371044020022d0000450d02200241016a21020c010b0b2002417c6a21020340200241046a22022802002203417f73200341fffdfb776a7141808182847871450d000b0340200341ff0171450d01200241016a2d00002103200241016a21020c000b000b20002001200220016b105020000b1d0020001051200041146a41003602002000420037020c2000200110160b8b0101037f230041306b22032400200341186a1011220220011052100f2002200341086a200110121017220128020c200141106a28020047044010000b200041003602082000420037020020012802042102200128020021042000412010532004200220002802002202200028020420026b1001200128020c22000440200120003602100b200341306a24000b8b0101017f024020012002460440410121030c010b4101210302400240200220016b2202410146044020012c0000417f4c0d010c030b200241374b0d010b200241016a21030c010b2002105420026a41016a21030b027f200041186a28020022010440200041086a280200200041146a280200200110550c010b20000b 2201200128020020036a36020020000b1300200028020820014904402000200110570b0b1600200020012802002200200128020420006b10581a0b190020001051200041146a41003602002000420037020c20000b4d01017f20004200370200200041086a2202410036020020012d0000410171450440200020012902003702002002200141086a28020036020020000f0b200020012802082001280204105020000bc30c02077f027e230041306b22042400200041046a2107027f20014101460440200041086a280200200041146a280200200041186a220228020022031055280200210120022003417f6a3602002007105a4180104f044020072000410c6a280200417c6a105b0b200141384f047f2001105420016a0520010b41016a2102200041186a28020022010440200041086a280200200041146a280200200110550c020b20000c010b02402007105a0d00200041146a28020022014180084f0440200020014180786a360214200041086a2201280200220228020021032001200241046a360200200420033602182007200441186a105c0c010b2000410c6a2802002202200041086a2802006b4102752203200041106a2205280200220620002802046b2201410275490440418020103a2105200220064704400240200028020c220120002802102202470d0020002802082203 200028020422064b04402000200320012003200320066b41027541016a417e6d41027422026a105d220136020c2000200028020820026a3602080c010b200441186a200220066b2201410175410120011b22012001410276200041106a105e2102200028020c210320002802082101034020012003470440200228020820012802003602002002200228020841046a360208200141046a21010c010b0b200029020421092000200229020037020420022009370200200029020c21092000200229020837020c200220093702082002105f200028020c21010b200120053602002000200028020c41046a36020c0c020b02402000280208220120002802042202470d00200028020c2203200028021022064904402000200120032003200620036b41027541016a41026d41027422026a106022013602082000200028020c20026a36020c0c010b200441186a200620026b2201410175410120011b2201200141036a410276200041106a105e2102200028020c210320002802082101034020012003470440200228020820012802003602002002200228020841046a360208200141046a21010c010b0b200029020421092000200229020037020420022009370200200029020c21092000200229020837020c200220093702082002105f200028020821010b2001417c6a200536020020002000 2802082201417c6a22023602082002280200210220002001360208200420023602182007200441186a105c0c010b20042001410175410120011b20032005105e2102418020103a2106024020022802082201200228020c2203470d0020022802042205200228020022084b04402002200520012005200520086b41027541016a417e6d41027422036a105d22013602082002200228020420036a3602040c010b200441186a200320086b2201410175410120011b22012001410276200241106a280200105e21032002280208210520022802042101034020012005470440200328020820012802003602002003200328020841046a360208200141046a21010c010b0b2002290200210920022003290200370200200320093702002002290208210920022003290208370208200320093702082003105f200228020821010b200120063602002002200228020841046a360208200028020c2105034020002802082005460440200028020421012000200228020036020420022001360200200228020421012002200536020420002001360208200029020c21092000200229020837020c200220093702082002105f052005417c6a210502402002280204220120022802002203470d0020022802082206200228020c22084904402002200120062006200820066b41027541016a41026d410274 22036a106022013602042002200228020820036a3602080c010b200441186a200820036b2201410175410120011b2201200141036a4102762002280210105e21062002280208210320022802042101034020012003470440200428022020012802003602002004200428022041046a360220200141046a21010c010b0b20022902002109200220042903183702002002290208210a20022004290320370208200420093703182004200a3703202006105f200228020421010b2001417c6a200528020036020020022002280204417c6a3602040c010b0b0b200441186a20071061200428021c410036020041012102200041186a0b2201200128020020026a360200200441306a240020000ba10101037f41012103024002400240200128020420012d00002202410176200241017122041b220241014d0440200241016b0d032001280208200141016a20041b2c0000417f4c0d010c030b200241374b0d010b200241016a21030c010b2002105420026a41016a21030b027f200041186a28020022010440200041086a280200200041146a280200200110550c010b20000b2201200128020020036a36020020000bea0101047f230041106b22042400200028020422012000280210220241087641fcffff07716a2103027f410020012000280208460d001a2003280200200241ff0771410274 6a0b2101200441086a20001061200428020c210203400240200120024604402000410036021420002802082103200028020421010340200320016b41027522024103490d022000200141046a22013602040c000b000b200141046a220120032802006b418020470d0120032802042101200341046a21030c010b0b2002417f6a220241014d04402000418004418008200241016b1b3602100b20002001105b200441106a24000b8e0201057f2001044020002802042105200041106a2802002202200041146a280200220349044020022001ad2005ad422086843702002000200028021041086a36021020000f0b027f41002002200028020c22046b410375220641016a2202200320046b2203410275220420042002491b41ffffffff01200341037541ffffffff00491b2204450d001a2004410374103a0b2102200220064103746a22032001ad2005ad4220868437020020032000280210200028020c22066b22016b2105200220044103746a2102200341086a2103200141014e044020052006200110361a0b20002002360214200020033602102000200536020c20000f0b200041c00110d201200041004100410110ce0120000b2c01017f20002001280208200141016a20012d0000220041017122021b2001280204200041017620021b10580bc80301087f230041c0016b2203240020 0341ac08100b2105200341e8006a4102100c2104200341d8006a2005100d200341c8006a2000100d200341406b4100360200200341386a4200370300200341306a420037030020034200370328200341286a20032802582205200328025c100e20032802482206200328024c100e210720042003280228100f2004200341d8006a10102004200341c8006a1010200428020c200441106a28020047044010000b2004280204210820042802002109200341106a1011210020034180016a200110122101200320023b018c01200341a8016a4100360200200341a0016a420037030020034198016a4200370300200342003703900120034190016a41001013200341b0016a200110121014220220032f018c0110192002410110132102200328029001210a200241046a10152000200a100f20004102101620034190016a200110121017220020032f018c01101a200028020c200041106a28020047044010000b20092008200028020020002802041007200028020c22010440200020013602100b200741046a1015200604402003200636024c0b200504402003200536025c0b200428020c22000440200420003602100b200341c0016a24000b0c0020002001ad420010561a0b0b0020002001ad420010590bf20301067f230041d0016b22052400200541086a419f08100b2107200541f0006a 4103100c2106200541e0006a2007100d200541d0006a2000100d200541c8006a4100360200200541406b4200370300200541386a420037030020054200370330200541306a200528026022002005280264100e200528025022072005280254100e22082001101920062005280230100f2006200541e0006a10102006200541d0006a101020062001101a200628020c200641106a28020047044010000b200628020421092006280200210a200541186a1011210120054188016a20021012210220052004360298012005200336029401200541b8016a4100360200200541b0016a4200370300200541a8016a4200370300200542003703a001200541a0016a41001013200541c0016a2002101210142203200528029401101920032005280298011019200341011013210320052802a0012104200341046a101520012004100f200141031016200541a0016a2002101210172201200528029401101a2001200528029801101a200128020c200141106a28020047044010000b200a2009200128020020012802041007200128020c22020440200120023602100b200841046a101520070440200520073602540b20000440200520003602640b200628020c22010440200620013602100b200541d0016a24000b2e01017f230041206b22022400200241106a418d08100b2002419908100b100a20 0020013a0010200241206a24000b3301017f230041206b22022400200241106a418008100b2002418708100b20011018200041286a20013b0100200241206a24000b3701017f230041206b22022400200241106a418008100b20012002418708100b20012001101b200041406b2001360200200241206a24000b930201047f20002001470440200128020420012d00002202410176200241017122041b2102200141016a210320012802082105410a21012005200320041b210420002d0000410171220304402000280200417e71417f6a21010b200220014d0440027f2003044020002802080c010b200041016a0b21012002044020012004200210490b200120026a41003a000020002d000041017104402000200236020420000f0b200020024101743a000020000f0b416f2103200141e6ffffff074d0440410b20014101742201200220022001491b220141106a4170712001410b491b21030b2003103a22012004200210c801200020023602042000200341017236020020002001360208200120026a41003a00000b20000b0d00200041b0016a20013a00000b0b00200041b0016a2c00000b230020002001101f1a2000410c6a2001410c6a101f1a200041186a200141186a101f1a0b25002000200110121a2000410c6a2001410c6a10121a200041186a200141186a10121a20000b0d 00200041c8026a20013a00000b0b00200041c8026a2c00000b9e0101047f2000200147044020012802042203200128020022026b41017522042000280208200028020022016b4101754d0440200041046a21052004200028020420016b41017522004b04402002200220004101746a22002001104e1a20002003200510460f0b2005200220032001104e3602000f0b2001044020004100360208200042003702000b200020002004104f104c20022003200041046a10460b0b3e01017f2000420037020020004100360208200128020420012802006b2202044020002002410175104c20012802002001280204200041046a10460b20000b3001027f200141046a21032001280200210203402002200346044020004188046a20011029052002102a21020c010b0b0be00201067f230041206b22042400024020002001460d00200141046a21062001280200210102402000280208450d00200028020021032000200041046a3602002000410036020820002802042102200041003602042002410036020820032802042202200320021b2102034020022203450d0120012006470440200341106a200141106a101f21072003411c6a2001411c6a101f1a024020032802082202450440410021020c010b2003200228020022054604402002410036020020022802042205450d01200510432102 0c010b200241003602042005450d002005104321020b2000200441106a2007104421072000200428021020072003103f2001102a21010c010b0b0340200328020822030d000b200621010b034020012006460d01200441106a2000200141106a104a20002004410c6a2004280210220341106a104421022000200428020c20022003103f2001102a21010c000b000b200441206a24000b3601017f024020002802042201044003402001220028020022010d000c020b000b0340200020002802082200280200470d000b0b20000bd60101067f230041106b22022400200042003702042000200041046a2203360200200141046a21062001280200210103402001200646450440200141106a21050240027f027f0240024020032000280200460440200321040c010b2003103b220441106a2005103c450d010b20032802004504402002200336020c2003210420030c030b2002200436020c200441046a0c010b20002002410c6a2005103d0b22042802000d01200228020c0b2107200220002005104a2000200720042002280200103f0b2001102a21010c010b0b200241106a240020000b2300200041d0016a2001101f1a20004198016a20033a0000200041f8026a20023602000b920101047f2000200147044020012802042203200128020022026b22042000280208200028020022016b 4d0440200041046a21052004200028020420016b22004b04402002200020026a2200200110471a20002003200510460f0b200520022003200110473602000f0b2001044020004100360208200042003702000b2000200020041048104520022003200041046a10460b0b3b01017f2000420037020020004100360208200128020420012802006b2202044020002002104520012802002001280204200041046a10460b20000b2601017f0340200241f800470440200020026a200120026a101f1a2002410c6a21020c010b0b0b2301017f0340200020026a200120026a10121a2002410c6a220241f800470d000b20000b130020002001101f1a2000200128020c36020c0b15002000200110121a2000200128020c36020c20000b3001027f200141046a210320012802002102034020022003460440200041f8066a20011034052002102a21020c010b0b0bd30201067f230041206b22042400024020002001460d00200141046a21062001280200210102402000280208450d00200028020021032000200041046a3602002000410036020820002802042102200041003602042002410036020820032802042202200320021b2102034020022203450d0120012006470440200341106a200141106a101f2107024020032802082202450440410021020c010b20032002280200220546044020 02410036020020022802042205450d012005104321020c010b200241003602042005450d002005104321020b2000200441106a2007104421072000200428021020072003103f2001102a21010c010b0b0340200328020822030d000b200621010b034020012006460d01200441106a2000200141106a103e20002004410c6a2004280210220341106a104421022000200428020c20022003103f2001102a21010c000b000b200441206a24000bd60101067f230041106b22022400200042003702042000200041046a2203360200200141046a21062001280200210103402001200646450440200141106a21050240027f027f0240024020032000280200460440200321040c010b2003103b220441106a2005103c450d010b20032802004504402002200336020c2003210420030c030b2002200436020c200441046a0c010b20002002410c6a2005103d0b22042802000d01200228020c0b2107200220002005103e2000200720042002280200103f0b2001102a21010c010b0b200241106a240020000bfc0801067f03400240200020046a2105200120046a210320022004460d002003410371450d00200520032d00003a0000200441016a21040c010b0b200220046b210602402005410371220745044003402006411049450440200020046a2203200120046a2205290200370200200341 086a200541086a290200370200200441106a2104200641706a21060c010b0b027f2006410871450440200120046a2103200020046a0c010b200020046a2205200120046a2204290200370200200441086a2103200541086a0b21042006410471044020042003280200360200200341046a2103200441046a21040b20064102710440200420032f00003b0000200341026a2103200441026a21040b2006410171450d01200420032d00003a000020000f0b024020064120490d002007417f6a220741024b0d00024002400240024002400240200741016b0e020102000b2005200120046a220328020022073a0000200541016a200341016a2f00003b0000200041036a2108200220046b417d6a2106034020064111490d03200420086a2203200120046a220541046a2802002202410874200741187672360200200341046a200541086a2802002207410874200241187672360200200341086a2005410c6a28020022024108742007411876723602002003410c6a200541106a2802002207410874200241187672360200200441106a2104200641706a21060c000b000b2005200120046a220328020022073a0000200541016a200341016a2d00003a0000200041026a2108200220046b417e6a2106034020064112490d03200420086a2203200120046a220541046a28020022024110742007 41107672360200200341046a200541086a2802002207411074200241107672360200200341086a2005410c6a28020022024110742007411076723602002003410c6a200541106a2802002207411074200241107672360200200441106a2104200641706a21060c000b000b2005200120046a28020022073a0000200041016a21082004417f7320026a2106034020064113490d03200420086a2203200120046a220541046a2802002202411874200741087672360200200341046a200541086a2802002207411874200241087672360200200341086a2005410c6a28020022024118742007410876723602002003410c6a200541106a2802002207411874200241087672360200200441106a2104200641706a21060c000b000b200120046a41036a2103200020046a41036a21050c020b200120046a41026a2103200020046a41026a21050c010b200120046a41016a2103200020046a41016a21050b20064110710440200520032d00003a00002005200328000136000120052003290005370005200520032f000d3b000d200520032d000f3a000f200541106a2105200341106a21030b2006410871044020052003290000370000200541086a2105200341086a21030b2006410471044020052003280000360000200541046a2105200341046a21030b20064102710440200520032f00003b 0000200541026a2105200341026a21030b2006410171450d00200520032d00003a00000b20000b2b01027f200141046a210203402002280200220341046a210220012003470d000b200041a80b6a200110380bbe0201057f024020002001460d00200041046a2102200141046a21030340200228020021020240027f4101200328020022032001460d001a20002002470d0141000b210402402000200246044020040d044114103a22054100360200200541086a200341086a10121a20052104410121060340200120032802042203460d024114103a220241086a200341086a10121a2002200436020020042002360204200641016a2106200221040c000b000b200228020022032000280200220128020436020420012802042003360200034020002002460d0420002000280208417f6a360208200228020421020c000b000b2000280200220220053602042005200236020020002004360200200420003602042000200028020820066a3602080c020b200241086a200341086a101f1a200241046a2102200341046a21030c000b000b0b840101037f200041003602082000200036020420002000360200200141046a2102037f20022802002203200146047f2000054114103a22024100360200200241086a200341086a10121a2002200036020420002802002104200020023602002002 2004360200200420023602042000200028020841016a360208200341046a21020c010b0b0b0b002000410120001b10620b3e01027f024020002802002201044003402001220228020422010d000c020b000b03402000280208220228020020004621012002210020010d000b0b20020bb20101067f02400240200128020420012d00002202410176200241017122031b2205200028020420002d00002202410176200241017122041b2206200520064922071b2202450d002000280208200041016a20041b21002001280208200141016a20031b210103402002450d0120002d0000220320012d00002204460440200141016a2101200041016a21002002417f6a21020c010b0b200320046b22020d010b417f200720062005491b21020b2002411f760b890101027f200041046a2103024020002802042200044002400340024002402002200041106a2204103c0440200028020022040d012001200036020020000f0b20042002103c450d03200041046a210320002802042204450d01200321000b20002103200421000c010b0b2001200036020020030f0b200120003602000c010b200120033602000b20030b2d01017f2000411c103a22033602002000200141046a360204200341106a200210121a200041086a41013a00000b4800200320013602082003420037020020022003360200 20002802002802002201044020002001360200200228020021030b2000280204200310402000200028020841016a3602080bec0101037f200120002001463a000c03400240024020002001460d00200128020822022d000c0d002002200228020822032802002204460440024020032802042204450d0020042d000c0d002004410c6a21010c030b20012002280200470440200210412002280208220228020821030b200241013a000c200341003a000c200310420f0b02402004450d0020042d000c0d002004410c6a21010c020b20012002280200460440200210422002280208220228020821030b200241013a000c200341003a000c200310410b0f0b200241013a000c200320002003463a000c200141013a0000200321010c000b000b5101027f200020002802042201280200220236020420020440200220003602080b200120002802083602082000280208220220022802002000474102746a200136020020002001360208200120003602000b5101027f200020002802002201280204220236020020020440200220003602080b200120002802083602082000280208220220022802002000474102746a200136020020002001360208200120003602040b1d01017f03402000220128020022000d00200128020422000d000b20010b5c01017f0240200028020422030440034002 402002200341106a103c044020032802002200450d040c010b200328020422000d0020012003360200200341046a0f0b200021030c000b000b200041046a21030b2001200336020020030b2001017f20002001103a2202360200200020023602042000200120026a3602080b2800200120006b220141014e044020022802002000200110361a2002200228020020016a3602000b0b1900200120006b2201044020022000200110490b200120026a0b2e01017f2001200028020820002802006b2200410174220220022001491b41ffffffff07200041ffffffff03491b0b8d0301037f024020002001460d00200120006b20026b410020024101746b4d044020002001200210361a0c010b20002001734103712103027f024020002001490440200020030d021a410021030340200120036a2105200020036a2204410371450440200220036b210241002103034020024104490d04200320046a200320056a280200360200200341046a21032002417c6a21020c000b000b20022003460d04200420052d00003a0000200341016a21030c000b000b024020030d002001417f6a21040340200020026a22034103714504402001417c6a21032000417c6a2104034020024104490d03200220046a200220036a2802003602002002417c6a21020c000b000b2002450d042003417f6a200220046a2d 00003a00002002417f6a21020c000b000b2001417f6a210103402002450d03200020026a417f6a200120026a2d00003a00002002417f6a21020c000b000b200320056a2101200320046a0b210303402002450d01200320012d00003a00002002417f6a2102200341016a2103200141016a21010c000b000b0b2c01017f20004128103a22033602002000200141046a360204200341106a2002104b200041086a41013a00000b16002000200110121a2000410c6a2001410c6a10121a0b2301017f20002001104d2202360200200020023602042000200220014101746a3602080b09002000410174103a0b2501017f200120006b220141017521032001044020022000200110490b200220034101746a0b2a002001200028020820002802006b220020002001491b41ffffffff07200041017541ffffffff03491b0b5b01027f02402002410a4d0440200020024101743a0000200041016a21030c010b200241106a4170712204103a21032000200236020420002004410172360200200020033602080b20032001200210c801200220036a41003a00000b160020004100360208200042003702002000410010570b5801027f230041306b22012400200141286a4100360200200141206a4200370300200141186a420037030020014200370310200141106a2001200010121014210020012802 102102200041046a1015200141306a240020020bdd0101047f024020002802042203200028020022026b22042001490440200028020820036b200120046b22024f04400340200341003a00002000200028020441016a22033602042002417f6a22020d000c030b000b200020011048220104402001103a21050b200420056a220421030340200341003a0000200341016a21032002417f6a22020d000b200120056a210520042000280204200028020022046b22016b2102200141014e044020022004200110361a0b2000200536020820002003360204200020023602000f0b200420014d0d002000200120026a3602040b0b1e01017f03402000044020004108762100200141016a21010c010b0b20010b25002000200120026a417f6a220241087641fcffff07716a280200200241ff07714102746a0b900101027f4101210420014280015441002002501b450440034020012002845045044020024238862001420888842101200341016a2103200242088821020c010b0b200341384f047f2003105420036a0520030b41016a21040b027f200041186a28020022030440200041086a280200200041146a280200200310550c010b20000b2203200328020020046a36020020000b2f01017f2000280208200149044020011062200028020020002802041036210220002001360208200020 023602000b0b7001017f4101210302400240024002402002410146044020012c000022024100480d012000200241ff017110d2010c040b200241374b0d01200221030b200020034180017341ff017110d2010c010b2000200210d301200221030b200020012003410010ce010b2000410110d00120000bcf0202037f027e02402001200284500440200041800110d2010c010b20014280015441002002501b4504402001210720022106034020062007845045044020064238862007420888842107200341016a2103200642088821060c010b0b0240200341384f04402003210403402004044020044108762104200541016a21050c010b0b200541c9004f044010000b2000200541b77f6a41ff017110d2012000200028020420056a10d101200028020420002802006a417f6a21052003210403402004450d02200520043a0000200441087621042005417f6a21050c000b000b200020034180017341ff017110d2010b2000200028020420036a10d101200028020420002802006a417f6a210303402001200284500d02200320013c0000200242388620014208888421012003417f6a2103200242088821020c000b000b20002001a741ff017110d2010b2000410110d0010b2801017f200028020820002802046b2201410874417f6a410020011b200028021420002802106a6b0b250101 7f200028020821020340200120024645044020002002417c6a22023602080c010b0b0ba10202057f017e230041206b22052400024020002802082202200028020c2203470d0020002802042204200028020022064b04402000200420022004200420066b41027541016a417e6d41027422036a105d22023602082000200028020420036a3602040c010b200541086a200320066b2202410175410120021b220220024102762000410c6a105e2103200028020821042000280204210203402002200446450440200328020820022802003602002003200328020841046a360208200241046a21020c010b0b2000290200210720002003290200370200200320073702002000290208210720002003290208370208200320073702082003105f200028020821020b200220012802003602002000200028020841046a360208200541206a24000b2501017f200120006b220141027521032001044020022000200110490b200220034102746a0b4f01017f2000410036020c200041106a2003360200200104402001410274103a21040b200020043602002000200420024102746a22023602082000200420014102746a36020c2000200236020420000b2b01027f200028020821012000280204210203402001200247044020002001417c6a22013602080c010b0b0b1b00200120006b2201044020 0220016b22022000200110490b20020b4f01037f20012802042203200128021020012802146a220441087641fcffff07716a21022000027f410020032001280208460d001a2002280200200441ff07714102746a0b360204200020023602000b9b0101047f230041106b220124002001200036020c2000047f41880c200041086a2202411076220041880c2802006a220336020041840c41840c280200220420026a41076a417871220236020002400240200341107420024d044041880c200341016a360200200041016a21000c010b2000450d010b200040000d0010000b20042001410c6a4104103641086a0541000b2100200141106a240020000b090010c701106410650bc52602057f027e230041c0166b2201240010022200106222021003200141d00a6a200141086a20022000106622004100106702400240200141d00a6a10682205500d0041c208106920055104402000106a200141d00a6a106b106c0c020b41c708106920055104402000106d410247044010000b200141d00a6a200041011067200141d00a6a106e2100200141d00a6a106b22022000101c2002106c0c020b41d008106920055104402000106a200141d00a6a106b22032d00102102200141b8086a101122002002106f100f20002002101a200028020c200041106a28020047044010000b2000280200200028 02041008200028020c22020440200020023602100b2003106c0c020b41d908106920055104402000106d410247044010000b200141d00a6a200041011067200141d00a6a10702100200141d00a6a106b22022000101d2002106c0c020b41e308106920055104402000106a200141d00a6a106b220341286a2f01002102200141b8086a1011220020021071100f20002002101a200028020c200041106a28020047044010000b200028020020002802041008200028020c22020440200020023602100b2003106c0c020b41ed08106920055104402000106d410247044010000b200141d00a6a200041011067200141d00a6a10722100200141d00a6a106b22022000101e2002106c0c020b41f708106920055104402000106a200141d00a6a106b220341406b2802002102200141b8086a1011220020021073100f20002002101a200028020c200041106a28020047044010000b200028020020002802041008200028020c22020440200020023602100b2003106c0c020b418109106920055104402000106d410247044010000b200141d00a6a200041011067200141d00a6a10682105200141d00a6a106b220041d8006a20053703002000106c0c020b418b09106920055104402000106a200141d00a6a106b220241d8006a2903002105200141b8086a1011220020051074100f2000200510 75200028020c200041106a28020047044010000b200028020020002802041008200028020c22030440200020033602100b2002106c0c020b41950910692005510440200141b8066a107621022000106d410247044010000b200141d00a6a200041011067200141d00a6a20021077200141d00a6a106b220041f8006a200141b8086a20021012101f1a2000106c0c020b419f09106920055104402000106a200141a0046a200141d00a6a106b220241f8006a10122100200141b8086a1011220320001052100f2003200141b8066a200010121017220028020c200041106a28020047044010000b200028020020002802041008200028020c22030440200020033602100b2002106c0c020b41a90910692005510440200141003a00b8082000106d410247044010000b200141d00a6a200041011067200141d00a6a200141b8086a1078200141d00a6a106b22004198016a20012d00b8083a00002000106c0c020b41b109106920055104402000106a200141d00a6a106b22034198016a2d00002102200141b8086a101122002002106f100f20002002101a200028020c200041106a28020047044010000b200028020020002802041008200028020c22020440200020023602100b2003106c0c020b41b909106920055104402000410110790c020b41c1091069200551044020004102107a0c02 0b41c90910692005510440200141b8066a107b2000106d410247044010000b200141d00a6a200041011067200141d00a6a200141b8066a107c200141d00a6a106b220041d0016a200141b8086a200141b8066a1012101f1a2000106c0c020b41d409106920055104402000106a200141b8066a200141d00a6a106b220241d0016a10121a200141b8086a10112200200141b8066a107d100f2000200141b8066a107e200028020c200041106a28020047044010000b200028020020002802041008200028020c22030440200020033602100b2002106c0c020b41df0910692005510440200141b8066a4124107f1a200141b8066a10800121022000106d410247044010000b200141d00a6a200041011067200141d00a6a2002108101200141d00a6a106b22004190026a200141b8086a2002102310222000106c0c020b41ec09106920055104402000106a200141b8086a200141d00a6a106b22034190026a10232102200141b8066a101122002002108201100f20002002108301200028020c200041106a28020047044010000b200028020020002802041008200028020c22020440200020023602100b2003106c0c020b41f909106920055104402000410310790c020b41810a1069200551044020004104107a0c020b41890a106920055104402000106d410247044010000b200141d00a6a 200041011067200141d00a6a1084012100200141d00a6a106b220241e0026a20003b01002002106c0c020b41920a106920055104402000106a200141d00a6a106b220341e0026a2e01002102200141b8086a101122002002108501100f20002002108601200028020c200041106a28020047044010000b200028020020002802041008200028020c22020440200020023602100b2003106c0c020b419b0a106920055104402000106d410247044010000b200141d00a6a200041011067200141d00a6a1087012100200141d00a6a106b220241f8026a20003602002002106c0c020b41a40a106920055104402000106a200141d00a6a106b220341f8026a2802002102200141b8086a101122002002108801100f20002002108601200028020c200041106a28020047044010000b200028020020002802041008200028020c22020440200020023602100b2003106c0c020b41ad0a106920055104402000106d410247044010000b200141d00a6a200041011067200141d00a6a1089012105200141d00a6a106b22004190036a20053703002000106c0c020b41b60a106920055104402000106a200141d00a6a106b22024190036a2903002105200141b8086a101122002005108a01100f20002005108b01200028020c200041106a28020047044010000b200028020020002802041008200028 020c22030440200020033602100b2002106c0c020b41bf0a10692005510440200141003602c006200142003703b8062000106d410247044010000b200141d00a6a200041011067200141d00a6a200141b8066a108c01200141d00a6a106b220241e0036a200141b8086a200141b8066a102722001026200028020022030440200020033602040b2002106c20012802b8062200450d02200120003602bc060c020b41c90a106920055104402000106a200141b8066a200141d00a6a106b220341e0036a10272102200141b8086a101122002002108d01100f20002002108e01200028020c200041106a28020047044010000b200028020020002802041008200028020c22040440200020043602100b200228020022000440200220003602040b2003106c0c020b41d30a10692005510440200142003702bc062001200141b8066a4104723602b8062000106d410247044010000b200141d00a6a200041011067200141d00a6a200141b8066a108f01200141d00a6a106b2200200141b8086a200141b8066a102b10282000106c0c020b41da0a106920055104402000106a200141b8066a200141d00a6a106b22034188046a102b2102200141b8086a101122002002109001100f20002002109101200028020c200041106a28020047044010000b200028020020002802041008200028020c2202 0440200020023602100b2003106c0c020b41e10a10692005510440200141b8086a107b200141003a00c808200141003602c408200141c8086a21022000106d410447044010000b200141d00a6a200041011067200141d00a6a200141b8086a107c200141d00a6a2000410210672001200141d00a6a1087013602c408200141d00a6a200041031067200141d00a6a20021078200141d00a6a106b2100200141b8066a200141b8086a10121a2000200141b8066a20012802c40820012d00c808102c2000106c0c020b41f10a10692005510440200141003602a804200142003703a0042000106d410247044010000b200141d00a6a200041011067200141d00a6a200141a0046a109201200141d00a6a106b220341b0046a200141b8086a200141b8066a200141a0046a102e2200102e2202102d200228020022040440200220043602040b200028020022020440200020023602040b2003106c20012802a0042200450d02200120003602a4040c020b41fa0a106920055104402000106a200141b8066a200141d00a6a106b220341b0046a102e2102200141b8086a1011220020022802002002280204109301100f200020021010200028020c200041106a28020047044010000b200028020020002802041008200028020c22040440200020043602100b20022802002200044020022000360204 0b2003106c0c020b41830b10692005510440200141b8066a41f800107f1a200141b8066a10940121022000106d410247044010000b200141d00a6a200041011067200141d00a6a2002109501200141d00a6a106b220041c0056a200141b8086a20021030102f2000106c0c020b418c0b106920055104402000106a200141b8086a200141d00a6a106b220341c0056a10302102200141b8066a101122002002109601100f20002002109701200028020c200041106a28020047044010000b200028020020002802041008200028020c22020440200020023602100b2003106c0c020b41950b10692005510440200141b8066a10980121022000106d410247044010000b200141d00a6a200041011067200141d00a6a2002109901200141d00a6a106b220041d0066a200141b8086a2002103210312000106c0c020b419d0b106920055104402000106a200141b8066a200141d00a6a106b220341d0066a10322102200141b8086a101122002002109a01100f20002002109b01200028020c200041106a28020047044010000b200028020020002802041008200028020c22020440200020023602100b2003106c0c020b41a50b10692005510440200142003702bc062001200141b8066a4104723602b8062000106d410247044010000b200141d00a6a200041011067200141d00a6a200141b806 6a109c01200141d00a6a106b2200200141b8086a200141b8066a103510332000106c0c020b41ac0b106920055104402000106a200141b8066a200141d00a6a106b220341f8066a10352102200141b8086a101122002002109d01100f20002002109e01200028020c200041106a28020047044010000b200028020020002802041008200028020c22020440200020023602100b2003106c0c020b41b30b10692005510440200141b8066a109f0121022000106d410247044010000b200141d00a6a200041011067200141d00a6a200210a001200141d00a6a106b2100200141206a200141b8066a41800210361a200141b8086a200141206a41800210361a20004190096a200141b8086a41800210361a2000106c0c020b41c00b106920055104402000106a200141a0026a200141d00a6a106b22024190096a41800210361a200141a0066a10112200200141a0026a10a101100f200141a0046a200141a0026a41800210361a200141b8066a200141a0046a41800210361a200141206a200141b8066a41800210361a200141b8086a200141206a41800210361a2000200141b8086a4180021058220028020c200041106a28020047044010000b200028020020002802041008200028020c22030440200020033602100b2002106c0c020b41cd0b10692005510440200141003602c00620012001 41b8066a3602bc062001200141b8066a3602b8062000106d410247044010000b200141d00a6a200041011067200141d00a6a200141b8066a10a201200141d00a6a106b2200200141b8086a200141b8066a103922021037200210a3012000106c200141b8066a10a3010c020b41d50b106920055104402000106a200141b8066a200141d00a6a106b220341a80b6a10392102200141b8086a10112200200210a401100f2000200210a501200028020c200041106a28020047044010000b200028020020002802041008200028020c22040440200020043602100b200210a3012003106c0c020b41dd0b10692005510440200141b8086a10a60121022000106d410247044010000b200141d00a6a200041011067200141d00a6a200210a701200141d00a6a106b2100200141b0066a200141c8086a2802002202360200200141a8066a200141c0086a2903002205370300200120012903b80822063703a006200041d80b6a2006370300200041e00b6a2005370300200041e80b6a20023602002000106c0c020b41e80b10692005520d002000106a200141306a2200200141d00a6a106b220241e80b6a280000360200200141286a2203200241e00b6a2900003703002001200241d80b6a290000370320200141b8086a10112204200141206a10a801100f200141b0026a20002802002200360200 200141a8026a200329030022053703002001200129032022063703a002200141a8046a2005370300200141b0046a2000360200200141a8066a2005370300200141b0066a2000360200200120063703a004200120063703a006200141c8066a2000360200200141c0066a2005370300200120063703b8062004200141b8066a41141058220028020c200041106a28020047044010000b200028020020002802041008200028020c22030440200020033602100b2002106c0c010b10000b200141c0166a24000b880101037f41f40b410136020041f80b2802002100034020000440034041fc0b41fc0b2802002201417f6a2202360200200141014845044041f40b4100360200200020024102746a22004184016a280200200041046a28020011030041f40b410136020041f80b28020021000c010b0b41fc0b412036020041f80b200028020022003602000c010b0b0b0d00200020012002411c10a9010bd00202067f017e230041106b220324002001280208220520024b0440200341086a200110cd0120012003280208200328020c10cb0136020c2003200110cd01410021052001027f410020032802002207450d001a410020032802042208200128020c2206490d001a200820062006417f461b210420070b360210200141146a2004360200200141003602080b200141106a2106034020 01280214210402402005200249044020040d01410021040b200020062802002004411410a9011a200341106a24000f0b2003200110cd0141002104027f410020032802002205450d001a410020032802042208200128020c2207490d001a200820076b2104200520076a0b210520012004360214200120053602102003200641002005200410cb0110cc012001200329030022093702102001200128020c2009422088a76a36020c2001200128020841016a22053602080c000b000b880102027f017e230041106b22012400200010aa0102400240200010ab01450d002000280204450d0020002802002d000041c001490d010b10000b200141086a200010ac01200128020c220041094f044010000b200128020821020340200004402000417f6a210020023100002003420886842103200241016a21020c010b0b200141106a240020030b3901027e42a5c688a1c89ca7f94b210103402000300000220250450440200041016a2100200142b383808080207e20028521010c010b0b20010b0e002000106d410147044010000b0bca2901097f230041406a22012400200042ddbe888dc5fcfca4987f370308200041003a0000200141286a1011220320002903081075200328020c200341106a28020047044010000b0240200328020022072003280204220810042205450d00200141003602 2020014200370318200141186a200510532007200820012802182204200128021c220620046b1005417f47044020002001200441016a20062004417f736a1066106e3a0010200521020b2004450d002001200436021c0b200328020c22040440200320043602100b2002450440200020002d00003a00100b41002102200041003b0118200041206a220442debe888dc5fcfca4987f370300200141286a1011220320042903001075200328020c200341106a28020047044010000b0240200328020022072003280204220810042205450d002001410036022020014200370318200141186a200510532007200820012802182204200128021c220620046b1005417f47044020002001200441016a20062004417f736a106610703b0128200521020b2004450d002001200436021c0b200328020c22040440200320043602100b2002450440200020002f01183b01280b4100210220004100360230200041386a220442dfbe888dc5fcfca4987f370300200141286a1011220320042903001075200328020c200341106a28020047044010000b0240200328020022072003280204220810042205450d002001410036022020014200370318200141186a200510532007200820012802182204200128021c220620046b1005417f47044020002001200441016a20062004417f736a106610723602 40200521020b2004450d002001200436021c0b200328020c22040440200320043602100b2002450440200020002802303602400b20004200370348200041d0006a220242d9be888dc5fcfca4987f370300200141286a1011220320022903001075200328020c200341106a28020047044010000b0240200328020022072003280204220810042205450440410021040c010b410021042001410036022020014200370318200141186a200510532007200820012802182202200128021c220620026b1005417f47044020002001200241016a20062002417f736a10661068370358200521040b2002450d002001200236021c0b200328020c22020440200320023602100b2004450440200020002903483703580b200041e0006a10762109200041f0006a220242a7cea8ad82a0ff995b370300200041f8006a10762107200141286a1011220320022903001075200328020c200341106a28020047044010000b0240200328020022082003280204220610042205450440410021040c010b410021042001410036022020014200370318200141186a200510532008200620012802182202200128021c220620026b1005417f4704402001200241016a20062002417f736a106620071077200521040b2002450d002001200236021c0b200328020c22020440200320023602100b20044504402007 2009101f1a0b41002102200041003a00880120004190016a220442f4a2efb3f6e5b8ad03370300200141286a1011220320042903001075200328020c200341106a28020047044010000b0240200328020022072003280204220810042205450d002001410036022020014200370318200141186a200510532007200820012802182204200128021c220620046b1005417f4704402001200441016a20062004417f736a106620004198016a1078200521020b2004450d002001200436021c0b200328020c22040440200320043602100b2002450440200020002d0088013a0098010b200041003a00a001200041a8016a220342badda0b2f6c5fa8e033703002003200041b0016a10ad01450440200020002d00a0013a00b0010b200042003703b801200041c0016a4100360200200041b8016a10762109200041c8016a2202428aedabfdf7a698fe29370300200041d0016a220710761a200141286a1011220320022903001075200328020c200341106a28020047044010000b0240200328020022082003280204220610042205450440410021040c010b410021042001410036022020014200370318200141186a200510532008200620012802182202200128021c220620026b1005417f4704402001200241016a20062002417f736a10662007107c200521040b2002450d00200120023602 1c0b200328020c22020440200320023602100b200445044020072009101f1a0b41002102200041e0016a4124107f108001210920004188026a220442d4b7b1edebf7e3f66a37030020004190026a1080012107200141286a1011220320042903001075200328020c200341106a28020047044010000b0240200328020022082003280204220610042205450d002001410036022020014200370318200141186a200510532008200620012802182204200128021c220620046b1005417f4704402001200441016a20062004417f736a10662007108101200521020b2004450d002001200436021c0b200328020c22040440200320043602100b20024504402007200910220b200041003a00b802200041c0026a220342ccacbdb4f8a587a93d3703002003200041c8026a10ad01450440200020002d00b8023a00c8020b200041003b01d002200041d8026a220242cfacbdb4f8a587a93d370300200141286a1011220320022903001075200328020c200341106a28020047044010000b0240200328020022072003280204220810042205450440410021040c010b410021042001410036022020014200370318200141186a200510532007200820012802182202200128021c220620026b1005417f47044020002001200241016a20062002417f736a10661084013b01e002200521040b200245 0d002001200236021c0b200328020c22020440200320023602100b2004450440200020002f01d0023b01e0020b41002102200041003602e802200041f0026a220442ceacbdb4f8a587a93d370300200141286a1011220320042903001075200328020c200341106a28020047044010000b0240200328020022072003280204220810042205450d002001410036022020014200370318200141186a200510532007200820012802182204200128021c220620046b1005417f47044020002001200441016a20062004417f736a10661087013602f802200521020b2004450d002001200436021c0b200328020c22040440200320043602100b2002450440200020002802e8023602f8020b200042003703800320004188036a220242c8acbdb4f8a587a93d370300200141286a1011220320022903001075200328020c200341106a28020047044010000b0240200328020022072003280204220810042205450440410021040c010b410021042001410036022020014200370318200141186a200510532007200820012802182202200128021c220620026b1005417f47044020002001200241016a20062002417f736a106610890137039003200521040b2002450d002001200236021c0b200328020c22020440200320023602100b20044504402000200029038003370390030b410021022000 410036029803200041a0036a220442e2e780dbeae4fcabe100370300200141286a1011220320042903001075200328020c200341106a28020047044010000b0240200328020022072003280204220810042205450d002001410036022020014200370318200141186a200510532007200820012802182204200128021c220620046b1005417f47044020002001200441016a20062004417f736a106610723602a803200521020b2004450d002001200436021c0b200328020c22040440200320043602100b200245044020002000280298033602a8030b200042003703b003200041b8036a220242b3debf9dbddf9ca832370300200141286a1011220320022903001075200328020c200341106a28020047044010000b0240200328020022072003280204220810042205450440410021040c010b410021042001410036022020014200370318200141186a200510532007200820012802182202200128021c220620026b1005417f47044020002001200241016a20062002417f736a106610683703c003200521040b2002450d002001200236021c0b200328020c22020440200320023602100b2004450440200020002903b0033703c0030b200042003702c80341002102200041e8036a4100360200200041e0036a22074200370200200041d8036a2204429fe6c89bc186c5be1d37030020 0041d0036a4100360200200141286a1011220320042903001075200328020c200341106a28020047044010000b0240200328020022082003280204220610042205450d002001410036022020014200370318200141186a200510532008200620012802182204200128021c220920046b1005417f4704402001200441016a20092004417f736a10662007108c01200521020b2004450d002001200436021c0b200328020c22040440200320043602100b20024504402007200041c8036a10260b200041f4036a220342003702002000418c046a2202420037020020004180046a2204428cbcadf0bacdb08975370300200020033602f00320004188046a22072002360200200141286a1011220320042903001075200328020c200341106a28020047044010000b0240200328020022082003280204220610042205450440410021040c010b410021042001410036022020014200370318200141186a200510532008200620012802182202200128021c220920026b1005417f4704402001200241016a20092002417f736a10662007108f01200521040b2002450d002001200236021c0b200328020c22020440200320023602100b20044504402007200041f0036a10290b200042003702980441002102200041b8046a4100360200200041b0046a22074200370200200041a8046a220442bd8c e2969cacfba4b07f370300200041a0046a4100360200200141286a1011220320042903001075200328020c200341106a28020047044010000b0240200328020022082003280204220610042205450d002001410036022020014200370318200141186a200510532008200620012802182204200128021c220920046b1005417f4704402001200441016a20092004417f736a10662007109201200521020b2004450d002001200436021c0b200328020c22040440200320043602100b2002450440200720004198046a102d0b41002102200041c0046a41f800107f1094012109200041b8056a2204429fa88ce0a0829ecea47f370300200041c0056a1094012107200141286a1011220320042903001075200328020c200341106a28020047044010000b0240200328020022082003280204220610042205450d002001410036022020014200370318200141186a200510532008200620012802182204200128021c220620046b1005417f4704402001200441016a20062004417f736a10662007109501200521020b2004450d002001200436021c0b200328020c22040440200320043602100b200245044020072009102f0b200041b8066a1098012109200041c8066a220242bcf8d4f484c7a18d807f370300200041d0066a1098012107200141286a1011220320022903001075200328020c 200341106a28020047044010000b0240200328020022082003280204220610042205450440410021040c010b410021042001410036022020014200370318200141186a200510532008200620012802182202200128021c220620026b1005417f4704402001200241016a20062002417f736a10662007109901200521040b2002450d002001200236021c0b200328020c22020440200320023602100b20044504402007200910310b200041e4066a22034200370200200041fc066a22024200370200200041f0066a220442eafdbbb690ac81edca00370300200020033602e006200041f8066a22072002360200200141286a1011220320042903001075200328020c200341106a28020047044010000b0240200328020022082003280204220610042205450440410021040c010b410021042001410036022020014200370318200141186a200510532008200620012802182202200128021c220920026b1005417f4704402001200241016a20092002417f736a10662007109c01200521040b2002450d002001200236021c0b200328020c22020440200320023602100b20044504402007200041e0066a10340b20004188076a2209109f011a20004188096a220242d0b4afbcbf988ce0b77f37030020004190096a109f012107200141286a1011220320022903001075200328020c20034110 6a28020047044010000b0240200328020022082003280204220610042205450440410021040c010b410021042001410036022020014200370318200141186a200510532008200620012802182202200128021c220620026b1005417f4704402001200241016a20062002417f736a1066200710a001200521040b2002450d002001200236021c0b200328020c22020440200320023602100b20044504402007200941800210361a0b41002104200041b00b6a4100360200200041ac0b6a200041a80b6a2202360200200041a00b6a220542f4ffce959b97c9c1d500370300200041980b6a4100360200200041940b6a200041900b6a2207360200200020073602900b20022002360200200141286a1011220320052903001075200328020c200341106a28020047044010000b0240200328020022062003280204220910042208450d002001410036022020014200370318200141186a200810532006200920012802182205200128021c220620056b1005417f4704402001200541016a20062005417f736a1066200210a201200821040b2005450d002001200536021c0b200328020c22050440200320053602100b20044504402002200710380b200041b80b6a220710a6011a200041d00b6a220242affad78bbfdecaa6f300370300200041d80b6a10a6012104200141286a10112203200229 03001075200328020c200341106a28020047044010000b0240200328020022062003280204220910042208450440410021050c010b410021052001410036022020014200370318200141186a200810532006200920012802182202200128021c220620026b1005417f4704402001200241016a20062002417f736a1066200410a701200821050b2002450d002001200236021c0b200328020c22020440200320023602100b200545044020042007290300370300200441106a200741106a280200360200200441086a200741086a2903003703000b200141406b240020000b953102087f027e230041c0086b22052400200541c0066a10112201200041d00b6a22022903001074100f200120022903001075200041d80b6a2102200128020c200141106a28020047044010000b2001280204210720012802002106200541c0046a10112104200210a8012108200420054180026a10ae01220310af012004200820032802046a20032802006b100f200541a0026a200241106a280000220836020020054198026a200241086a290000220937030020052002290000220a37039002200541b0026a2009370300200541b8026a2008360200200541086a2009370300200541106a20083602002005200a3703a8022005200a370300200541d0026a2008360200200541c8026a20093703002005200a 3703c00202402004200541c0026a41141058220228020c200241106a280200460440200241046a2104200228020021080c010b200241046a2104100020022802002108200228020c2002280210460d0010000b20062007200820042802001006200328020022040440200320043602040b200228020c22030440200220033602100b200128020c22020440200120023602100b200541c0066a10112202200041a00b6a22012903001074100f200220012903001075200041a80b6a2104200228020c200241106a28020047044010000b2002280204210820022802002107200541c0046a10112101200410a40121062001200541c0026a10ae01220310af012001200620032802046a20032802006b100f2001200410a5010240200128020c200141106a280200460440200141046a2104200128020021060c010b200141046a2104100020012802002106200128020c2001280210460d0010000b20072008200620042802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200041a80b6a10a301200041900b6a10a301200541a8026a1011220120004188096a22022903001074100f20012002290300107520004190096a2104200128020c200141106a28020047044010000b20012802042108200128 0200210720054190026a10112102200410a1012106200220054180026a10ae01220310af012002200620032802046a20032802006b100f200520044180021036220541c0026a200541800210361a200541c0046a200541c0026a41800210361a200541c0066a200541c0046a41800210361a02402002200541c0066a4180021058220228020c200241106a280200460440200241046a2104200228020021060c010b200241046a2104100020022802002106200228020c2002280210460d0010000b20072008200620042802001006200328020022040440200320043602040b200228020c22030440200220033602100b200128020c22020440200120023602100b200541c0066a10112202200041f0066a22012903001074100f200220012903001075200041f8066a2104200228020c200241106a28020047044010000b2002280204210820022802002107200541c0046a101121012004109d0121062001200541c0026a10ae01220310af012001200620032802046a20032802006b100f20012004109e010240200128020c200141106a280200460440200141046a2104200128020021060c010b200141046a2104100020012802002106200128020c2001280210460d0010000b20072008200620042802001006200328020022040440200320043602040b200128020c22030440200120 033602100b200228020c22010440200220013602100b200541c0066a10112202200041c8066a22012903001074100f200220012903001075200041d0066a2104200228020c200241106a28020047044010000b2002280204210820022802002107200541c0046a101121012004109a0121062001200541c0026a10ae01220310af012001200620032802046a20032802006b100f20012004109b010240200128020c200141106a280200460440200141046a2104200128020021060c010b200141046a2104100020012802002106200128020c2001280210460d0010000b20072008200620042802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a10112202200041b8056a22012903001074100f200220012903001075200041c0056a2104200228020c200241106a28020047044010000b2002280204210820022802002107200541c0046a10112101200410960121062001200541c0026a10ae01220310af012001200620032802046a20032802006b100f200120041097010240200128020c200141106a280200460440200141046a2104200128020021060c010b200141046a2104100020012802002106200128020c2001280210460d0010000b2007200820062004280200100620 0328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a10112202200041a8046a22012903001074100f200220012903001075200041b0046a2104200228020c200241106a28020047044010000b2002280204210820022802002107200541c0046a1011210120002802b004200041b4046a28020010930121062001200541c0026a10ae01220310af012001200620032802046a20032802006b100f2001200410100240200128020c200141106a280200460440200141046a2104200128020021060c010b200141046a2104100020012802002106200128020c2001280210460d0010000b20072008200620042802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200041b0046a28020022010440200041b4046a20013602000b200028029804220104402000419c046a20013602000b200541c0066a1011220220004180046a22012903001074100f20022001290300107520004188046a2104200228020c200241106a28020047044010000b2002280204210820022802002107200541c0046a10112101200410900121062001200541c0026a10ae01220310af012001200620032802046a20032802006b100f20 0120041091010240200128020c200141106a280200460440200141046a2104200128020021060c010b200141046a2104100020012802002106200128020c2001280210460d0010000b20072008200620042802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a10112202200041d8036a22012903001074100f200220012903001075200041e0036a2104200228020c200241106a28020047044010000b2002280204210820022802002107200541c0046a101121012004108d0121062001200541c0026a10ae01220310af012001200620032802046a20032802006b100f20012004108e010240200128020c200141106a280200460440200141046a2104200128020021060c010b200141046a2104100020012802002106200128020c2001280210460d0010000b20072008200620042802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200041e0036a28020022010440200041e4036a20013602000b20002802c80322010440200041cc036a20013602000b200541c0046a10112202200041b8036a22012903001074100f200220012903001075200228020c200241106a2802004704401000 0b2002280204210420022802002108200541c0026a10112101200541d8066a4100360200200541d0066a4200370300200541c8066a4200370300200542003703c006200541c0066a20002903c00310b00120052802c0062107200541c0066a41047210152001200541c0066a10ae01220310af012001200720032802046a20032802006b100f200120002903c00310750240200128020c200141106a280200460440200141046a2107200128020021060c010b200141046a2107100020012802002106200128020c2001280210460d0010000b20082004200620072802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0046a10112202200041a0036a22012903001074100f200220012903001075200228020c200241106a28020047044010000b2002280204210420022802002108200541c0026a10112101200541d8066a4100360200200541d0066a4200370300200541c8066a4200370300200542003703c006200541c0066a20002802a803101920052802c0062107200541c0066a41047210152001200541c0066a10ae01220310af012001200720032802046a20032802006b100f200120002802a803101a0240200128020c200141106a280200460440200141046a21072001280200 21060c010b200141046a2107100020012802002106200128020c2001280210460d0010000b20082004200620072802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a1011220220004188036a22012903001074100f200220012903001075200228020c200241106a28020047044010000b2002280204210420022802002108200541c0046a10112101200029039003108a0121072001200541c0026a10ae01220310af012001200720032802046a20032802006b100f2001200029039003108b010240200128020c200141106a280200460440200141046a2107200128020021060c010b200141046a2107100020012802002106200128020c2001280210460d0010000b20082004200620072802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a10112202200041f0026a22012903001074100f200220012903001075200228020c200241106a28020047044010000b2002280204210420022802002108200541c0046a1011210120002802f80210880121072001200541c0026a10ae01220310af012001200720032802046a20032802006b100f200120002802f8021086010240 200128020c200141106a280200460440200141046a2107200128020021060c010b200141046a2107100020012802002106200128020c2001280210460d0010000b20082004200620072802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a10112202200041d8026a22012903001074100f200220012903001075200228020c200241106a28020047044010000b2002280204210420022802002108200541c0046a1011210120002f01e00210850121072001200541c0026a10ae01220310af012001200720032802046a20032802006b100f200120002e01e0021086010240200128020c200141106a280200460440200141046a2107200128020021060c010b200141046a2107100020012802002106200128020c2001280210460d0010000b20082004200620072802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200041c0026a200041c8026a10b101200541c0066a1011220220004188026a22012903001074100f20022001290300107520004190026a2104200228020c200241106a28020047044010000b2002280204210820022802002107200541c0046a1011210120041082012106 2001200541c0026a10ae01220310af012001200620032802046a20032802006b100f200120041083010240200128020c200141106a280200460440200141046a2104200128020021060c010b200141046a2104100020012802002106200128020c2001280210460d0010000b20072008200620042802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a10112202200041c8016a22012903001074100f200220012903001075200041d0016a2104200228020c200241106a28020047044010000b2002280204210820022802002107200541c0046a101121012004107d21062001200541c0026a10ae01220310af012001200620032802046a20032802006b100f20012004107e0240200128020c200141106a280200460440200141046a2104200128020021060c010b200141046a2104100020012802002106200128020c2001280210460d0010000b20072008200620042802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200041a8016a200041b0016a10b101200541c0066a1011220220004190016a22012903001074100f200220012903001075200228020c200241106a28020047044010 000b2002280204210420022802002108200541c0046a1011210120002d009801106f21072001200541c0026a10ae01220310af012001200720032802046a20032802006b100f200120002d009801101a0240200128020c200141106a280200460440200141046a2107200128020021060c010b200141046a2107100020012802002106200128020c2001280210460d0010000b20082004200620072802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a10112201200041f0006a22022903001074100f200120022903001075200041f8006a2104200128020c200141106a28020047044010000b2001280204210820012802002107200541c0046a101121022004105221062002200541c0026a10ae01220310af012002200620032802046a20032802006b100f024020022005200410121017220228020c200241106a280200460440200241046a2104200228020021060c010b200241046a2104100020022802002106200228020c2002280210460d0010000b20072008200620042802001006200328020022040440200320043602040b200228020c22030440200220033602100b200128020c22020440200120023602100b200541c0066a10112202200041d0006a22012903001074 100f200220012903001075200228020c200241106a28020047044010000b2002280204210420022802002108200541c0046a101121012000290358107421072001200541c0026a10ae01220310af012001200720032802046a20032802006b100f2001200029035810750240200128020c200141106a280200460440200141046a2107200128020021060c010b200141046a2107100020012802002106200128020c2001280210460d0010000b20082004200620072802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a10112202200041386a22012903001074100f200220012903001075200228020c200241106a28020047044010000b2002280204210420022802002108200541c0046a101121012000280240107321072001200541c0026a10ae01220310af012001200720032802046a20032802006b100f20012000280240101a0240200128020c200141106a280200460440200141046a2107200128020021060c010b200141046a2107100020012802002106200128020c2001280210460d0010000b20082004200620072802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0 066a10112202200041206a22012903001074100f200220012903001075200228020c200241106a28020047044010000b2002280204210420022802002108200541c0046a1011210120002f0128107121072001200541c0026a10ae01220310af012001200720032802046a20032802006b100f200120002f0128101a0240200128020c200141106a280200460440200141046a2107200128020021060c010b200141046a2107100020012802002106200128020c2001280210460d0010000b20082004200620072802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a1011220220002903081074100f200220002903081075200228020c200241106a28020047044010000b2002280204210420022802002108200541c0046a1011210120002d0010106f21072001200541c0026a10ae01220310af012001200720032802046a20032802006b100f200120002d0010101a0240200128020c200141106a280200460440200141046a2107200128020021060c010b200141046a2107100020012802002106200128020c2001280210460d0010000b20082004200620072802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c220104 40200220013602100b200541c0086a24000b2601017f02402000280204450d0020002802002d000041c001490d00200010b20121010b20010b800101037f230041106b22012400200010aa0102400240200010ab01450d002000280204450d0020002802002d000041c001490d010b10000b200141086a200010ac01200128020c220041024f044010000b200128020821020340200004402000417f6a210020022d00002103200241016a21020c010b0b200141106a240020030b5801027f230041206b22012400200141186a4100360200200141106a4200370300200141086a42003703002001420037030020012000ad42ff018342001056210020012802002102200041046a1015200141206a240020020b8b0101037f230041106b22012400200010aa0102400240200010ab01450d002000280204450d0020002802002d000041c001490d010b10000b200141086a200010ac01200128020c220041034f044010000b200128020821030340200004402000417f6a210020032d00002002410874722102200341016a21030c010b0b200141106a2400200241ffff03710b5401017f230041206b22012400200141186a4100360200200141106a4200370300200141086a4200370300200142003703002001200041ffff037110192001280200210020014104721015200141206a240020 000b860101037f230041106b22012400200010aa0102400240200010ab01450d002000280204450d0020002802002d000041c001490d010b10000b200141086a200010ac01200128020c220041054f044010000b200128020821030340200004402000417f6a210020032d00002002410874722102200341016a21030c010b0b200141106a240020020b4f01017f230041206b22012400200141186a4100360200200141106a4200370300200141086a4200370300200142003703002001200010192001280200210020014104721015200141206a240020000b5001027f230041206b22012400200141186a4100360200200141106a4200370300200141086a4200370300200142003703002001200010b0012001280200210220014104721015200141206a240020020b0a0020002001420010590b1a0020004200370200200041086a4100360200200010b30120000ba40201057f230041206b22022400024002402000280204044020002802002d000041c001490d010b200241086a10761a0c010b200241186a200010ac01200010b40121030240024002400240200228021822000440200228021c220520034f0d010b41002100200241106a410036020020024200370308410021050c010b200241106a4100360200200242003703082000200520032003417f461b22046a2105200441 0a4b0d010b200220044101743a0008200241086a41017221030c010b200441106a4170712206103a21032002200436020c20022006410172360208200220033602100b03402000200546450440200320002d00003a0000200341016a2103200041016a21000c010b0b200341003a00000b2001200241086a10b501200241206a24000b0e0020012000106e4100473a00000b4401027f230041f00b6b220224002000106d410247044010000b2002200041011067200210b60121002002106b21032002200020011100002003106c200241f00b6a24000b7b01027f230041900c6b220224002000106a200241086a106b2103200241086a20011101002100200241f80b6a10112201200010b701100f20012000108601200128020c200141106a28020047044010000b200128020020012802041008200128020c22000440200120003602100b2003106c200241900c6a24000b180020004200370200200041086a4100360200200010761a0b2801017f230041206b22022400200241086a200041001067200241086a20011077200241206a24000b5001017f230041206b22012400200141186a4100360200200141106a4200370300200141086a4200370300200142003703002001200010b8012001280200210020014104721015200141206a240020000b6e01027f230041406a2202240020 00410110162100200241386a4100360200200241306a4200370300200241286a420037030020024200370320200241206a200241106a200110121014210320002002280220100f200020022001101210171a200341046a1015200241406b24000be10201027f02402001450d00200041003a0000200020016a2203417f6a41003a000020014103490d00200041003a0002200041003a00012003417d6a41003a00002003417e6a41003a000020014107490d00200041003a00032003417c6a41003a000020014109490d002000410020006b41037122026a220341003602002003200120026b417c7122026a2201417c6a410036020020024109490d002003410036020820034100360204200141786a4100360200200141746a410036020020024119490d002003410036021820034100360214200341003602102003410036020c200141706a41003602002001416c6a4100360200200141686a4100360200200141646a41003602002002200341047141187222026b2101200220036a2102034020014120490d0120024200370300200241186a4200370300200241106a4200370300200241086a4200370300200241206a2102200141606a21010c000b000b20000b1900200010761a2000410c6a10761a200041186a10761a20000b5601017f230041206b22022400200241086a20004100 1067200241086a2001107c200241086a200041011067200241086a2001410c6a1077200241086a200041021067200241086a200141186a1077200241206a24000b7a01027f230041406a22012400200141186a4100360200200141106a4200370300200141086a4200370300200142003703002001410010132202200010b8012002200141306a2000410c6a10121014200141206a200041186a1012101441011013210020012802002102200041046a1015200141406b240020020ba30101047f230041e0006b220224002000410310162100200241d8006a4100360200200241d0006a4200370300200241c8006a420037030020024200370340200241406b200110b801200241406b200241306a2001410c6a220310121014200241206a200141186a220410121014210520002002280240100f20002001107e2000200241106a20031012101720022004101210171a200541046a1015200241e0006a24000b3902017f017e230041106b220124002001200010b90120012903002102200141106a2400420020024201837d200242018885a74110744110750b6202027f017e230041206b22012400200141186a4100360200200141106a4200370300200141086a42003703002001420037030020012000ad42308622034230872003423f8710ba01210020012802002102200041046a1015 200141206a240020020b1301017e20002001ac22022002423f8710bb010b3302017f017e230041106b220124002001200010b90120012903002102200141106a2400420020024201837d200242018885a70b5201027f230041206b22012400200141186a4100360200200141106a4200370300200141086a4200370300200142003703002001200010bc01210020012802002102200041046a1015200141206a240020020b4202017f027e230041106b220124002001200010b901200141086a290300210320012903002102200141106a2400420020024201837d2003423f86200242018884850b5701037f230041206b22012400200141186a4100360200200141106a4200370300200141086a420037030020014200370300200120002000423f8710ba01210220012802002103200241046a1015200141206a240020030b0e00200020012001423f8710bb010bb10201047f230041d0006b22022400024002402000280204450d0020002802002d000041c001490d002000106d21032001280208200128020022046b4101752003490440200120022003200128020420046b410175200141086a10bd01220310be01200310bf010b200241286a200010c001200241186a200010c101200141086a21050340200228022c200228021c46044020022802302002280220460d030b2002200241 286a10c2012002107021030240200128020422002001280208490440200020033b01002001200041026a3602040c010b200241386a2001200020012802006b410175220041016a104f2000200510bd0121002002280240220420033b01002002200441026a3602402001200010be01200010bf010b200241286a10c3010c000b000b10000b200241d0006a24000b9c0101037f230041206b22012400200141186a4100360200200141106a4200370300200141086a420037030020014200370300024020002802002000280204460440200110c4010c010b200141001013210220002802042103200028020021000340200020034604402002410110131a05200220002f01001019200041026a21000c010b0b0b2001280200210020014104721015200141206a240020000b4301017f2000200128020420012802006b410175101621022001280204210020012802002101034020002001470440200220012f0100101a200141026a21010c010b0b0be20201057f23004190016b22022400024002402000280204450d0020002802002d000041c001490d00200241c8006a200010c001200241386a200010c101200241146a21040340200228024c200228023c46044020022802502002280240460d030b200241206a200241c8006a10c201200241086a10762100200410762105200241206a 10c501410247044010000b20024180016a10762103200241e8006a200241206a41001067200241e8006a200310772000200310b501200241d8006a10762103200241e8006a200241206a41011067200241e8006a200310772005200310b5012001200241e8006a2000103d22062802004504404128103a22032002290308370210200341186a200241106a280200360200200010b301200341246a200441086a2802003602002003411c6a2004290200370200200510b3012001200228026820062003103f0b200241c8006a10c3010c000b000b10000b20024190016a24000bd00101047f230041e0006b22012400200141206a4100360200200141186a4200370300200141106a42003703002001420037030802402000280208450440200141086a10c4010c010b200041046a2103200141086a410010132102200141346a2104200028020021000340200020034604402002410110131a05200141286a200041106a104b200241001013200141d0006a200141286a10121014200141406b200410121014410110131a2000102a21000c010b0b0b20012802082100200141086a4104721015200141e0006a240020000b6101027f230041206b220224002000200128020810162103200141046a210020012802002101034020002001460440200241206a240005200341021016200241106a 200141106a1012101720022001411c6a101210171a2001102a21010c010b0b0bce0101037f230041206b22022400024002402000280204044020002802002d000041c001490d010b20024100360208200242003703000c010b200241186a200010ac0120022802182103200241106a200010ac0120022802102104200010b40121002002410036020820024200370300200020046a20036b2200450d0020022000104520004101480d002002200228020420032000103620006a3602040b2001280200044020014100360208200142003702000b2001200228020036020020012002290204370204200241206a24000b5301017f230041206b22022400200241186a4100360200200241106a4200370300200241086a420037030020024200370300200220002001100e210020022802002101200041046a1015200241206a240020010b2c01037f200041f8006a21022000210103402001107621032001410c6a21012003410c6a2002470d000b20000b6101037f230041306b22022400200010c501410a47044010000b03402003410a460440200241306a240005200241206a10762104200241086a200020031067200241086a200410772001200410b5012001410c6a2101200341016a21030c010b0b0b800101037f230041306b22012400200141186a4100360200200141106a42003703 00200141086a42003703002001420037030020014100101321030340200241f800464504402003200141206a200020026a101210141a2002410c6a21020c010b0b200341011013210220012802002103200241046a1015200141306a240020030b4401027f230041106b220224002000410a10162103410021000340200041f800460440200241106a24000520032002200020016a101210171a2000410c6a21000c010b0b0b1000200010761a2000410036020c20000b5d01027f230041306b22022400200010c501410247044010000b200241206a10762103200241086a200041001067200241086a200310772001200310b501200241086a2000410110672001200241086a10870136020c200241306a24000b7301027f230041406a22012400200141286a4100360200200141206a4200370300200141186a4200370300200142003703102001200010322100200141106a41001013200141306a200010121014200028020c10bc0141011013210020012802102102200041046a1015200141406b240020020b2a01017f230041106b220224002000410210162002200110121017200128020c108601200241106a24000bd70101047f230041d0006b22022400024002402000280204450d0020002802002d000041c001490d00200241406b200010c001200241306a200010c101200241 106a210403402002280244200228023446044020022802482002280238460d030b200241186a200241406b10c201200241186a200241086a1076220010772001200241cc006a2000103d2205280200450440411c103a22032002290308370210200341186a2004280200360200200010b3012001200228024c20052003103f0b200241406b10c3010c000b000b10000b200241d0006a24000b9e0101037f230041306b22012400200141186a4100360200200141106a4200370300200141086a42003703002001420037030002402000280208450440200110c4010c010b200041046a21032001410010132102200028020021000340200020034604402002410110131a052002200141206a200041106a101210141a2000102a21000c010b0b0b2001280200210020014104721015200141306a240020000b4f01027f230041106b220224002000200128020810162103200141046a210020012802002101034020002001460440200241106a24000520032002200141106a101210171a2001102a21010c010b0b0b2601017f0340200141800246450440200020016a41003a0000200141016a21010c010b0b20000b990101027f23004190046b22022400200010aa0120024188046a200010ac01200228028c042103024002402000280204450d0020034180024b0d0020002802002d000041 c001490d010b10000b20024188026a109f0120034180022003418002491b22006b4180026a200228028804200010361a200241086a20024188026a41800210361a2001200241086a41800210361a20024190046a24000bc00101037f230041a0086b2201240020014198026a410036020020014190026a420037030020014188026a42003703002001420037038002200120004180021036220041a0026a200041800210361a200041a0046a200041a0026a41800210361a200041a0066a200041a0046a41800210361a41012103024003402002418002460d01200041a0066a20026a2101200241016a210220012d0000450d000b41830221030b200020033602800220004180026a4104721015200041a0086a240020030bec0101037f230041d0006b22022400024002402000280204450d0020002802002d000041c001490d00200241406b200010c001200241306a200010c101200241106a210403402002280244200228023446044020022802482002280238460d030b200241186a200241406b10c201200241186a200241086a1076220310774114103a2200410036020020002002290308370208200041106a2004280200360200200310b30120002001360204200128020021032001200036020020002003360200200320003602042001200128020841016a360208200241406b10 c3010c000b000b10000b200241d0006a24000b4d01037f02402000280208450d00200028020422012802002202200028020022032802043602042000410036020820032802042002360200034020002001460d01200128020421010c000b000b0b9d0101037f230041306b22012400200141186a4100360200200141106a4200370300200141086a42003703002001420037030002402000280208450440200110c4010c010b200041046a2102200141001013210303402002280200220220004604402003410110131a052003200141206a200241086a101210141a200241046a21020c010b0b0b2001280200210220014104721015200141306a240020020b4e01027f230041106b22032400200141046a210220002001280208101621000340200228020022022001460440200341106a24000520002003200241086a101210171a200241046a21020c010b0b0b2501017f03402001411446450440200020016a41003a0000200141016a21010c010b0b20000bbe0102027f027e230041406a22022400200010aa01200241386a200010ac01200228023c2103024002402000280204450d00200341144b0d0020002802002d000041c001490d010b10000b200241206a10a6012003411420034114491b22006b41146a2002280238200010361a200241186a200241306a2802002200360200 200241106a200241286a2903002204370300200220022903202205370308200141106a2000360000200141086a200437000020012005370000200241406b24000b850202037f027e23004180016b22012400200141306a4100360200200141286a4200370300200141206a4200370300200141086a200041086a2900002204370300200141106a200041106a280000220236020020014200370318200120002900002205370300200141406b2004370300200141c8006a2002360200200141d8006a2004370300200141e0006a20023602002001200537033820012005370350200141f8006a2002360200200141f0006a200437030020012005370368410121020240034020034114460d01200141e8006a20036a2100200341016a210320002d0000450d000b411521020b20012002360218200141186a410472101520014180016a240020020b750020004200370210200042ffffffff0f370208200020023602042000200136020002402003410871450d00200010c90120024f0d002003410471044010000c010b200042003702000b02402003411071450d00200010c90120024d0d0020034104710440100020000f0b200042003702000b20000b4101017f200028020445044010000b0240200028020022012d0000418101470d00200028020441014d047f100020002802000520010b 2c00014100480d0010000b0b990101037f200028020445044041000f0b200010aa01200028020022022c0000220141004e044020014100470f0b027f4101200141807f460d001a200141ff0171220341b7014d0440200028020441014d047f100020002802000520020b2d00014100470f0b4100200341bf014b0d001a2000280204200141ff017141ca7e6a22014d047f100020002802000520020b20016a2d00004100470b0bd60101047f200110b4012204200128020422024b04401000200128020421020b200128020021052000027f02400240200204404100210120052c00002203417f4a0d01027f200341ff0171220141bf014d04404100200341ff017141b801490d011a200141c97e6a0c010b4100200341ff017141f801490d001a200141897e6a0b41016a21010c010b4101210120050d000c010b41002103200120046a20024b0d0020022001490d00410020022004490d011a200120056a2103200220016b20042004417f461b0c010b41000b360204200020033602000bc20101057f230041406a22022400200241286a1011220320002903001075200328020c200341106a28020047044010000b02402003280200220020032802042205100422064504400c010b2002410036022020024200370318200241186a200610532000200520022802182200200228021c220520 006b1005417f47044020012002200041016a20052000417f736a106610b6013a0000200621040b2000450d002002200036021c0b200328020c22000440200320003602100b200241406b240020040b30002000410036020820004200370200200041011045200028020441fe013a00002000200028020441016a36020420000b6101037f200028020c200041106a28020047044010000b200028020422022001280204200128020022036b22016a220420002802084b047f20002004105720002802040520020b20002802006a2003200110361a2000200028020420016a3602040b0b0020002001420010561a0b8e0201067f230041406a22042400200441286a1011220220002903001074100f200220002903001075200228020c200241106a28020047044010000b2002280204210620022802002107200441106a1011210020012d000010b70121052000200410ae01220310af012000200520032802046a20032802006b100f200020012c00001086010240200028020c200041106a280200460440200041046a2101200028020021050c010b200041046a2101100020002802002105200028020c2000280210460d0010000b20072006200520012802001006200328020022010440200320013602040b200028020c22030440200020033602100b200228020c22000440200220003602 100b200441406b24000b820101047f230041106b2201240002402000280204450d0020002802002d000041c001490d00200141086a200010cd01200128020c210003402000450d0120014100200128020822032003200010cb0122046a20034520002004497222031b3602084100200020046b20031b2100200241016a21020c000b000b200141106a240020020b2201017f03402001410c470440200020016a4100360200200141046a21010c010b0b0b800301037f200028020445044041000f0b200010aa0141012102024020002802002c00002201417f4a0d00200141ff0171220341b7014d0440200341807f6a0f0b02400240200141ff0171220141bf014d0440024020002802042201200341c97e6a22024d047f100020002802040520010b4102490d0020002802002d00010d0010000b200241054f044010000b20002802002d000145044010000b4100210241b7012101034020012003460440200241384f0d030c0405200028020020016a41ca7e6a2d00002002410874722102200141016a21010c010b000b000b200141f7014d0440200341c07e6a0f0b024020002802042201200341897e6a22024d047f100020002802040520010b4102490d0020002802002d00010d0010000b200241054f044010000b20002802002d000145044010000b4100210241f701210103402001 200346044020024138490d0305200028020020016a418a7e6a2d00002002410874722102200141016a21010c010b0b0b200241ff7d490d010b10000b20020b5c00024020002d0000410171450440200041003b01000c010b200028020841003a00002000410036020420002d0000410171450d00200041003602000b20002001290200370200200041086a200141086a280200360200200110b3010b3902017f017e230041106b220124002001200010b90120012903002102200141106a2400420020024201837d200242018885a74118744118750b6202027f017e230041206b22012400200141186a4100360200200141106a4200370300200141086a42003703002001420037030020012000ad42388622034238872003423f8710ba01210020012802002102200041046a1015200141206a240020020b2701017f230041106b220224002000410010132002200110121014410110131a200241106a24000ba10102027f027e230041106b22022400200110aa0102400240200110ab01450d002001280204450d0020012802002d000041c001490d010b10000b200241086a200110ac01200228020c220141114f044010000b20022802082103034020010440200542088620044238888421052001417f6a210120033100002004420886842104200341016a21030c010b0b200020043703 0020002005370308200241106a24000b2301017e20002002423f87220320014201868520024201862001423f888420038510560b2301017e20002002423f87220320014201868520024201862001423f888420038510590b1301017e20002001ac22022002423f8710ba010b4c01017f2000410036020c200041106a2003360200200104402001104d21040b200020043602002000200420024101746a22023602082000200420014101746a36020c2000200236020420000b870101037f200120012802042000280204200028020022046b22036b2202360204200341004a044020022004200310361a200128020421020b200028020021032000200236020020012003360204200028020421022000200128020836020420012002360208200028020821022000200128020c3602082001200236020c200120012802043602000b2b01027f200028020821012000280204210203402001200247044020002001417e6a22013602080c010b0b0b0b0020002001410110c6010b0b0020002001410010c6010b170020002001280204200141086a280200411c10a9011a0bb70102057f017e230041106b22032400200041046a210102402000280200220204402001280200220504402005200041086a2802006a21040b20002004360204200041086a2002360200200341086a20014100200420 0210cb0110cc0120002003290308220637020420004100200028020022012006422088a76b2202200220014b1b3602000c010b200020012802002201047f2001200041086a2802006a0541000b360204200041086a41003602000b200341106a24000b3901017f027f200041186a28020022010440200041086a280200200041146a280200200110550c010b20000b2201200128020041016a3602000b220002402000280204044020002802002d000041bf014b0d010b10000b200010b2010be70101037f230041106b2204240020004200370200200041086a410036020020012802042103024002402002450440200321020c010b410021022003450d002003210220012802002d000041c001490d00200441086a200110cd0120004100200428020c220120042802082202200110cb0122032003417f461b20024520012003497222031b220536020820004100200220031b3602042000200120056b3602000c010b20012802002103200128020421012000410036020020004100200220016b20034520022001497222021b36020820004100200120036a20021b3602040b200441106a24000b3501017f230041106b220041908c0436020c41800c200028020c41076a417871220036020041840c200036020041880c3f003602000b10002002044020002001200210361a0b0b3001017f 200028020445044041000f0b4101210120002802002c0000417f4c047f200010ca01200010b4016a0520010b0b5b00027f027f41002000280204450d001a410020002802002c0000417f4a0d011a20002802002d0000220041bf014d04404100200041b801490d011a200041c97e6a0c010b4100200041f801490d001a200041897e6a0b41016a0b0b2901017f230041206b22022400200241086a20002001411410a90110c9012100200241206a240020000b5b01027f2000027f0240200128020022054504400c010b200220036a200128020422014b0d0020012002490d00410020012003490d011a200220056a2104200120026b20032003417f461b0c010b41000b360204200020043602000b2401017f200110b401220220012802044b044010000b20002001200110ca01200210cc010b2f002000200210cf01200028020020002802046a2001200210361a2000200028020420026a3602042000200310d0010b1b00200028020420016a220120002802084b04402000200110570b0b830201047f02402001450d00034020002802102202200028020c460d01200241786a28020020014904401000200028021021020b200241786a2203200328020020016b220136020020010d012000200336021020004101200028020422032002417c6a28020022016b22021054220441016a2002 4138491b220520036a10d101200120002802006a220320056a2003200210490240200241374d0440200028020020016a200241406a3a00000c010b200441f7016a220341ff014d0440200028020020016a20033a00002000280200200120046a6a210103402002450d02200120023a0000200241087621022001417f6a21010c000b000b10000b410121010c000b000b0b0f00200020011057200020013602040b26002000410110cf01200028020020002802046a20013a00002000200028020441016a3602040b6001027f20011054220241b7016a22034180024e044010000b2000200341ff017110d2012000200028020420026a10d101200028020420002802006a417f6a2100034020010440200020013a0000200141087621012000417f6a21000c010b0b0b0bfa0301004180080bf203746f70696331006461746131006a735f636f6e7472616374006576656e740073657455696e7433324576740073657455696e743136457674007472616e7366657200696e69740073657455696e74380067657455696e74380073657455696e7431360067657455696e7431360073657455696e7433320067657455696e7433320073657455696e7436340067657455696e74363400736574537472696e6700676574537472696e6700736574426f6f6c00676574426f6f6c0073657443686172 0067657443686172007365744d657373616765006765744d657373616765007365744d794d657373616765006765744d794d65737361676500736574496e743800676574496e743800736574496e74313600676574496e74313600736574496e74333200676574496e74333200736574496e74363400676574496e74363400736574566563746f7200676574566563746f72007365744d6170006765744d617000746573744d756c7469506172616d730073657442797465730067657442797465730073657441727261790067657441727261790073657450616972006765745061697200736574536574006765745365740073657446697865644861736800676574466978656448617368007365744c697374006765744c69737400736574416464726573730067657441646472657373' + cabi = [{"constant":false,"input":[{"name":"input","type":"string[10]"}],"name":"setArray","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getUint32","output":"uint32","type":"Action"},{"constant":false,"input":[{"name":"input","type":"int64"}],"name":"setInt64","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getInt64","output":"int64","type":"Action"},{"constant":false,"input":[{"name":"input","type":"pair"}],"name":"setPair","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getPair","output":"pair","type":"Action"},{"anonymous":false,"input":[{"name":"topic","type":"string"},{"name":"arg1","type":"string"}],"name":"transfer","topic":1,"type":"Event"},{"anonymous":false,"input":[{"name":"topic","type":"string"},{"name":"arg1","type":"string"},{"name":"arg2","type":"uint16"}],"name":"setUint16Evt","topic":1,"type":"Event"},{"constant":false,"input":[{"name":"addr","type":"FixedHash<20>"}],"name":"setAddress","output":"void","type":"Action"},{"anonymous":false,"input":[{"name":"topic1","type":"string"},{"name":"topic2","type":"uint32"},{"name":"arg1","type":"string"},{"name":"arg2","type":"uint32"},{"name":"arg3","type":"uint32"}],"name":"setUint32Evt","topic":2,"type":"Event"},{"constant":false,"input":[],"name":"init","output":"void","type":"Action"},{"constant":false,"input":[{"name":"input","type":"uint8"}],"name":"setUint8","output":"void","type":"Action"},{"baseclass":[],"fields":[{"name":"head","type":"string"}],"name":"message","type":"struct"},{"constant":false,"input":[{"name":"msg","type":"message"}],"name":"setMessage","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getUint8","output":"uint8","type":"Action"},{"constant":false,"input":[{"name":"input","type":"uint16"}],"name":"setUint16","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getUint16","output":"uint16","type":"Action"},{"constant":false,"input":[{"name":"input","type":"uint32"}],"name":"setUint32","output":"void","type":"Action"},{"constant":false,"input":[{"name":"input","type":"uint64"}],"name":"setUint64","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getUint64","output":"uint64","type":"Action"},{"constant":false,"input":[{"name":"input","type":"string"}],"name":"setString","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getString","output":"string","type":"Action"},{"constant":false,"input":[{"name":"input","type":"bool"}],"name":"setBool","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getBool","output":"bool","type":"Action"},{"constant":false,"input":[{"name":"input","type":"int8"}],"name":"setChar","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getChar","output":"int8","type":"Action"},{"constant":true,"input":[],"name":"getMessage","output":"message","type":"Action"},{"baseclass":["message"],"fields":[{"name":"body","type":"string"},{"name":"end","type":"string"}],"name":"my_message","type":"struct"},{"constant":false,"input":[{"name":"msg","type":"my_message"}],"name":"setMyMessage","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getMyMessage","output":"my_message","type":"Action"},{"constant":false,"input":[{"name":"input","type":"int8"}],"name":"setInt8","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getSet","output":"set","type":"Action"},{"constant":true,"input":[],"name":"getInt8","output":"int8","type":"Action"},{"constant":false,"input":[{"name":"input","type":"int16"}],"name":"setInt16","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getInt16","output":"int16","type":"Action"},{"constant":false,"input":[{"name":"input","type":"int32"}],"name":"setInt32","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getInt32","output":"int32","type":"Action"},{"constant":false,"input":[{"name":"vec","type":"uint16[]"}],"name":"setVector","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getVector","output":"uint16[]","type":"Action"},{"constant":false,"input":[{"name":"input","type":"map"}],"name":"setMap","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getMap","output":"map","type":"Action"},{"constant":false,"input":[{"name":"msg","type":"message"},{"name":"input1","type":"int32"},{"name":"input2","type":"bool"}],"name":"testMultiParams","output":"void","type":"Action"},{"constant":false,"input":[{"name":"input","type":"uint8[]"}],"name":"setBytes","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getBytes","output":"uint8[]","type":"Action"},{"constant":true,"input":[],"name":"getArray","output":"string[10]","type":"Action"},{"constant":false,"input":[{"name":"input","type":"set"}],"name":"setSet","output":"void","type":"Action"},{"constant":false,"input":[{"name":"input","type":"FixedHash<256>"}],"name":"setFixedHash","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getFixedHash","output":"FixedHash<256>","type":"Action"},{"constant":false,"input":[{"name":"input","type":"list"}],"name":"setList","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getList","output":"list","type":"Action"},{"constant":true,"input":[],"name":"getAddress","output":"FixedHash<20>","type":"Action"}] + + ``` + + The wasm type contract creates a contract instance through platon.wasmcontract + + Call the method .constructor() on the instance to construct the contract, and send the transaction to the chain through transact + +```python + # Instantiate and deploy contract +Payable = platon.wasmcontract(abi=cabi, bytecode=bytecode,vmtype=1) + +tx_hash = Payable.constructor().transact( + { + 'from':from_address, + 'gas': 1500000, + } + ) + + # Wait for the transaction to be mined, and get the transaction receipt + tx_receipt = platon.waitForTransactionReceipt(tx_hash) + print(tx_receipt) +``` + + Among them, tx_receipt is the transaction receipt of the deployment contract + + After the deployment is successful, the output is as follows + +``` + #Output +AttributeDict ({ 'blockHash': HexBytes ( '0x7a193be2cf86aedcf844c0478c6f64d226affb55779bad1b2056c7e70e8158d6'), 'blockNumber': 2012981, 'contractAddress':' lax15sh4rpuqr4fvzs4cyj9uea54r5tax7kljqqszk ',' cumulativeGasUsed ': 1233168,' from ':' lax1uqug0zq7rcxddndleq4ux2ft3tv6dqljphydrl ',' gasUsed ': 1233168,' logs ': [],' logsBloom ': HexBytes (' 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 '),' status': 1, 'to': None, 'transactionHash': HexBytes ( '0x717a82ea0ef116e271fb02dbb7d456fe9dd41a2dbd07cac81d079e375b5dade1'), 'transactionIndex': 0} ) + +``` + +##### (3) Send transaction to Helloworld contract (wasm contract) + + ​ Based on the successful deployment of the previous contract, call the method in the contract. + + ​ payable is an instance after the contract is successfully deployed + + ​ By calling the function setBool, the parameter false is sent to the chain (send transaction) + + ```python + payable = platon.wasmcontract(address=tx_receipt.contractAddress, abi=cabi,vmtype=1) + + tx_hash0 = payable.functions.setBool(false).transact( + { + 'from':from_address, + 'gas': 1500000, + } + ) + print(platon.waitForTransactionReceipt(tx_hash0)) + print('get: {}'.format( + payable.functions.getBool().call() + )) + ``` + + payable.functions.getBool().call(), which means that the corresponding information on the chain is obtained through the function getBool (according to the definition of this contract, the parameters uploaded by setBool are obtained). + + After successful operation, the results are as follows: + + ```python + #Output + AttributeDict({'blockHash': HexBytes('0x9bcadf4db5d74789901b2176cb7dad3191d2425b61f261966e932f6606d13041'),'blockNumber': 2018575,'contractAddress': None,'cumulativeq [], 'logsBloom': HexBytes ( '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'), 'status': 1, 'to': 'lax1c5h59flven2hzyrylh2tsmn59r5ucms95n5ugc', 'transactionHash': HexBytes ( '0x4c724e7d1833ade363f51f611293682771318e3c86b533f5a78b580c812eb009'), 'transactionIndex': 0}) + get: False + ``` + +##### (4) Event call of wasm contract + + Events in the wasm contract are generally written in the function of the contract. + + Take the wasmcontract contract as an example, the method setUint32 contains the event setUint32Evt, and setUint32Evt can be used to monitor and log the transaction results of setUint32. + + Greeter is an example of a successfully deployed wasm type contract + + tx_hash is a transaction instance of function setUint32 passing parameters + + ```python + greeter = platon.wasmcontract(address=tx_receipt.contractAddress, abi=abi,vmtype=1) + tx_hash = greeter.functions.setUint32(1000).transact( + { + 'from': from_address, + 'gas': 1500000, + } + ) + + tx_receipt = platon.waitForTransactionReceipt(tx_hash) + print(tx_receipt) + + topic_param = greeter.events.setUint32Evt().processReceipt(tx_receipt) +print(topic_param) + ``` + + topic_param is the result of the event setUint32Evt call + + The output after successful operation is as follows: + + ```python +(AttributeDict(('args': AttributeDict(('topic1':'topic1','arg1':'data1','arg2': 1000,'arg3': 1000}),'event':'setUint32Evt', ' logIndex ': 0,' transactionIndex ': 0,' transactionHash ': HexBytes (' 0xabac50c6a9d443d9f89065775f0f3d56ddeabd2f2a5e0e1f36d00db703b14d8b '),' address': 'lax1sgsp74pce2vkgwqjd3rzmt55p70psmq7qvnqwn', 'blockHash': HexBytes ( '0x78f15fbacbc745dfd5b35b596d28b61ae2987b6ff9050dc39c716f383e505899'), 'blockNumber': 1477774}),) + ``` + + Among the values ​​​​corresponding to'args': + + 'topic1' is the topic value,'arg1','arg2', and'arg3' are the three parameter values ​​defined in the event. + + + +### Four part: Ppos + +#### Special note + +- node_id + - When the node_id parameter needs to be passed in each api , '0x' should be removed. + +#### 1.staking + +```python +from client_sdk_python import Web3, HTTPProvider +from client_sdk_python.ppos import Ppos +w3 = Web3(HTTPProvider("http://localhost:6789"),chain_id = 100) +ppos = Ppos(w3) +``` + +##### Initiate a pledge + +Calling method + +``` +ppos.createStaking(benifit_address, node_id, external_id, node_name, website, details, amount,program_version,program_version_sign, bls_pubkey, bls_proof, pri_key, reward_per, typ=2, transaction_cfg=None) +``` + +Parameter Description + +- **typ**: Indicates whether the account free amount or the account's lock amount is used for staking, 0: free amount; 1: lock amount;2: Give priority to lock amount, use free amount provided that staking amount over lock amount. + +- **benifit_address**: Income account for accepting block rewards and staking rewards. + +- **node_id**: The idled node Id (also called the candidate's node Id). + +- **external_id**: External Id (with length limit, Id for the third party to pull the node description). + +- **node_name**: The name of the staking node (with a length limit indicating the name of the node). + +- **website**: The third-party home page of the node (with a length limit indicating the home page of the node). + +- **details**: Description of the node (with a length limit indicating the description of the node). + +- **amount**: staking von (unit:von, 1LAT = 10\*\*18 von). + +- **program_version**: The real version of the program, admin_getProgramVersion. + +- **program_version_sign**: The real version of the program is signed, admin_getProgramVersion. + +- **bls_pubkey**: Bls public key. + +- **bls_proof**: Proof of bls, obtained by pulling the proof interface, admin_getSchnorrNIZKProve. + +- **pri_key**: Private key for transaction. + +- **reward_per**: Proportion of the reward share obtained from the commission, using BasePoint 1BP = 0.01%. + +- **transaction_cfg**: Transaction basic configuration. + + ~~~ + type: + dict + example: + cfg = { + "gas":100000000, + "gasPrice":2000000000000, + "nonce":1, + } + ~~~ + + + +##### Modify pledge information + +Calling method + +``` +ppos.editCandidate(benifit_address, node_id, external_id, node_name, website, details, pri_key, reward_per, transaction_cfg=None) +``` + +Parameter Description + +- **benifit_address**: Income account for accepting block rewards and staking rewards. + +- **node_id**: The idled node Id (also called the candidate's node Id). + +- **external_id**: External Id (with length limit, Id for the third party to pull the node description). + +- **node_name**: The name of the staking node (with a length limit indicating the name of the node). + +- **website**: The third-party home page of the node (with a length limit indicating the home page of the node). + +- **details**: Description of the node (with a length limit indicating the description of the node). + +- **pri_key**: Private key for transaction. + +- **reward_per**: Proportion of the reward share obtained from the commission, using BasePoint 1BP = 0.01%. + +- **transaction_cfg**: Transaction basic configuration. + + ~~~ + type: + dict + example: + cfg = { + "gas":100000000, + "gasPrice":2000000000000, + "nonce":1, + } + ~~~ + + + +##### Increase stake + +Calling method + +``` +ppos.increaseStaking(node_id, amount, pri_key, typ=2, transaction_cfg=None) +``` + +Parameter Description + +- **typ**: Indicates whether the account free amount or the account's lock amount is used for staking, 0: free amount; 1: lock amount;2: Give priority to lock amount, use free amount provided that staking amount over lock amount. + +- **node_id**: The idled node Id (also called the candidate's node Id). + +- **amount**: staking von (unit:von, 1LAT = 10\*\*18 von). + +- **pri_key**: Private key for transaction. + +- **transaction_cfg**: Transaction basic configuration.. + + ~~~ + type: + dict + example: + cfg = { + "gas":100000000, + "gasPrice":2000000000000, + "nonce":1, + } + ~~~ + + + +##### Cancel the pledge (initiate all cancellation at one time, and arrive at the account multiple times) + +Calling method + +``` +ppos.withdrewStaking(node_id, pri_key, transaction_cfg=None) +``` + +Parameter Description + +- **node_id**: The idled node Id (also called the candidate's node Id). + +- **pri_key**: Private key for transaction. + +- **transaction_cfg**: Transaction basic configuration. + + ~~~ + type: + dict + example: + cfg = { + "gas":100000000, + "gasPrice":2000000000000, + "nonce":1, + } + ~~~ + + + +#### 2 .delegate + +##### Initiate a delegation + +Calling method + +``` +ppos.delegate(typ, node_id, amount, pri_key, transaction_cfg=None) +``` + +Parameter Description + +- **typ**: Indicates whether the account free amount or the account's lock amount is used for delegate, 0: free amount; 1: lock amount. + +- **node_id**: The idled node Id (also called the candidate's node Id). + +- **amount**: Amount of delegate (unit:von, 1LAT = 10\*\*18 von). + +- **pri_key**: Private key for transaction. + +- **transaction_cfg**: Transaction basic configuration. + + ~~~ + type: + dict + example: + cfg = { + "gas":100000000, + "gasPrice":2000000000000, + "nonce":1, + } + ~~~ + + + +##### Shareholding reduction/revocation commission + +Calling method + +``` +ppos.withdrewDelegate(staking_blocknum, node_id, amount, pri_key, transaction_cfg=None) +``` + +Parameter Description + +- **staking_blocknum**: A unique indication of a pledge of a node. + +- **node_id**: The idled node Id (also called the candidate's node Id). + +- **amount**: The amount of the entrusted reduction (unit:von, 1LAT = 10\*\*18 von). + +- **pri_key**: Private key for transaction. + +- **transaction_cfg**: Transaction basic configuration. + + ~~~ + type: + dict + example: + cfg = { + "gas":100000000, + "gasPrice":2000000000000, + "nonce":1, + } + ~~~ + + + +##### Withdrawing delegated rewards + +Calling method + +``` +ppos.withdrawDelegateReward(pri_key, transaction_cfg=None) +``` + +Parameter Description + +- **pri_key**: Private key for transaction. + +- **transaction_cfg**: Transaction basic configuration. + + ~~~ + type: + dict + example: + cfg = { + "gas":100000000, + "gasPrice":2000000000000, + "nonce":1, + } + ~~~ + + + +#### 3.query + +##### Query the validator queue of the current settlement cycle + +Calling method + +``` +ppos.getVerifierList(from_address=None) +``` + +Parameter Description + +- **from_address**: Used to call the rpc call method. + +##### Query the list of validators in the current consensus cycle + +Calling method + +``` +ppos.getValidatorList(from_address=None) +``` + +Parameter Description + +- **from_address**: Used to call the rpc call method. + +##### Query the list of all real-time candidates + +Calling method + +``` +ppos.getCandidateList(from_address=None) +``` + +Parameter Description + +- **from_address**: Used to call the rpc call method. + +##### Query the NodeID and pledge Id of the node entrusted by the current account address + +Calling method + +``` +ppos.getRelatedListByDelAddr(del_addr, from_address=None) +``` + +Parameter Description + +- **del_addr**: Client's account address. +- **from_address**: Used to call the rpc call method. + +##### Query the current delegation information of a single node + +Calling method + +``` +ppos.getDelegateInfo(staking_blocknum, del_address, node_id, from_address=None) +``` + +Parameter Description + +- **staking_blocknum**: Block height at the time of staking. +- **del_address**: Client's account address. +- **node_id**: Verifier's node ID. +- **from_address**: Used to call the rpc call method. + +##### Query the pledge information of the current node + +Calling method + +``` +ppos.getCandidateInfo(node_id, from_address=None) +``` + +Parameter Description + +- **node_id**: Verifier's node ID. +- **from_address**: Used to call the rpc call method. + +##### Query the block reward of the current settlement cycle + +Calling method + +``` +ppos.getPackageReward(from_address=None) +``` + +Parameter Description + +- **from_address**: Used to call the rpc call method. + +##### Query the pledge reward of the current settlement cycle + +Calling method + +``` +ppos.getStakingReward(from_address=None) +``` + +Parameter Description + +- **from_address**: Used to call the rpc call method. + +##### Query the average time of packing blocks + +Calling method + +``` +ppos.getAvgPackTime(from_address=None) +``` + +Parameter Description + +- **from_address**: Used to call the rpc call method. + +##### The query account has not withdrawn commission rewards at each node. + +Calling method + +``` +ppos.getDelegateReward(address, node_ids=[]) +``` + +Parameter Description + +- **address**:account address to be queried. +- **node_ids**:the string array of the node id to be queried, if it is empty, query all nodes delegated by the account. + +#### 4. Double sign + +##### Report double sign + +Calling method + +``` +ppos.reportDuplicateSign(typ, data, pri_key, transaction_cfg=None) +``` + +Parameter Description + +- **typ**: Represents duplicate sign type, 1:prepareBlock, 2: prepareVote, 3:viewChange. + +- **data**: Json value of single evidence, format reference RPC interface Evidences. + +- **pri_key**: Private key for transaction. + +- **transaction_cfg**: Transaction basic configuration. + + ~~~ + type: + dict + example: + cfg = { + "gas":100000000, + "gasPrice":2000000000000, + "nonce":1, + } + ~~~ + + + +##### Query whether the node has been reported too much signature + +Calling method + +``` +ppos.checkDuplicateSign(typ, node_id, block_number, from_address=None) +``` + +Parameter Description + +- **typ**: Represents double sign type, 1:prepareBlock, 2: prepareVote, 3:viewChange. +- **check_address**: Reported node address. +- **block_number**: Duplicate-signed block height. +- **from_address**: Used to call the rpc call method. + +#### 5. Lock position + +##### Create a hedging plan + +Calling method + +``` +ppos.createRestrictingPlan(account, plan, pri_key, transaction_cfg=None) +``` + +Parameter Description + +- **account**: Locked account release account. + +- **plan**: + An is a list of `RestrictingPlan` types (array), and `RestrictingPlan` is defined as follows: + + ~~~ + type RestrictingPlan struct { + Epoch uint64 + Amount *big.Int + } + ~~~ + + - where Epoch: represents a multiple of the billing period. + The product of the number of blocks per billing cycle indicates that the locked fund + s are released at the target block height. Epoch * The number of blocks per cycle is + at least greater than the maximum irreversible block height. + - Amount: indicates the amount to be released on the target block. + +- **pri_key**: Private key for transaction. + +- **transaction_cfg**: Transaction basic configuration. + + ~~~ + type: + dict + example: + cfg = { + "gas":100000000, + "gasPrice":2000000000000, + "nonce":1, + } + ~~~ + + + +##### Get lock information + +Calling method + +``` +ppos.getRestrictingInfo(account, from_address=None) +``` + +Parameter Description + +- **account**: Locked account release account. +- **from_address**: Used to call the rpc call method. + +#### 6. Governance + +```python +from client_sdk_python import Web3, HTTPProvider +from client_sdk_python.pip import Pip +w3 = Web3(HTTPProvider("http://localhost:6789"),chain_id = 100) +pip = Pip(w3) +``` + +##### Text proposal + +Calling method + +``` +pip.submitText(verifier, pip_id, pri_key, transaction_cfg=None) +``` + +Parameter Description + +- **verifier**: The certified submitting the proposal. + +- **pip_id**: PIPID. + +- **pri_key**: Private key for transaction. + +- **transaction_cfg**: Transaction basic configuration. + + ~~~ + type: + dict + example: + cfg = { + "gas":100000000, + "gasPrice":2000000000000, + "nonce":1, + } + ~~~ + + + +##### Upgrade proposal + +Calling method + +``` +pip.submitVersion(verifier, pip_id, new_version, end_voting_rounds, pri_key, transaction_cfg=None) +``` + +Parameter Description + +- **verifier**: The certified submitting the proposal. + +- **pip_id**: PIPID. + +- **new_version**: upgraded version. + +- **end_voting_rounds**: The number of voting consensus rounds. + Explanation: Assume that the transaction submitted by the proposal is rounded when the consensus round + number of the package is packed into the block, then the proposal voting block is high, + which is the 230th block height of the round of the round1 + endVotingRounds + (assuming a consensus round out of block 250, ppos The list is 20 blocks high in advance, + 250, 20 are configurable), where 0 .createFilter") @@ -771,7 +799,7 @@ def _encode_constructor_data(cls, args=None, kwargs=None): arguments = merge_args_and_kwargs(constructor_abi, args, kwargs) deploy_data = add_0x_prefix( - encode_abi(cls.web3, constructor_abi, arguments, data=cls.bytecode) + encode_abi(cls.web3, constructor_abi, arguments, cls.vmtype, cls.bytecode, cls.abi) ) else: deploy_data = to_hex(cls.bytecode) @@ -791,10 +819,11 @@ class ContractConstructor: """ Class for contract constructor API. """ - def __init__(self, web3, abi, bytecode, *args, **kwargs): + def __init__(self, web3, abi, bytecode,vmtype, *args, **kwargs): self.web3 = web3 self.abi = abi self.bytecode = bytecode + self.vmtype = vmtype self.data_in_transaction = self._encode_data_in_transaction(*args, **kwargs) @combomethod @@ -809,7 +838,7 @@ def _encode_data_in_transaction(self, *args, **kwargs): arguments = merge_args_and_kwargs(constructor_abi, args, kwargs) data = add_0x_prefix( - encode_abi(self.web3, constructor_abi, arguments, data=self.bytecode) + encode_abi(self.web3, constructor_abi, arguments, self.vmtype, self.bytecode, self.abi) ) else: data = to_hex(self.bytecode) @@ -1014,6 +1043,7 @@ class ContractFunction: abi = None transaction = None arguments = None + vmtype=None def __init__(self, abi=None): self.abi = abi @@ -1035,12 +1065,17 @@ def __call__(self, *args, **kwargs): def _set_function_info(self): if not self.abi: - self.abi = find_matching_fn_abi( - self.contract_abi, - self.function_identifier, - self.args, - self.kwargs - ) + if self.vmtype: + self.abi = find_wasm_abi( + self.contract_abi, + self.function_identifier) + else: + self.abi = find_matching_fn_abi( + self.contract_abi, + self.function_identifier, + self.args, + self.kwargs + ) if self.function_identifier is FallbackFn: self.selector = encode_hex(b'') elif is_text(self.function_identifier): @@ -1050,7 +1085,7 @@ def _set_function_info(self): self.arguments = merge_args_and_kwargs(self.abi, self.args, self.kwargs) - def call(self, transaction=None, block_identifier='latest'): + def call(self, transaction=None, block_identifier='latest', hrp=DEFAULTHRP): """ Execute a contract function call using the `platon_call` interface. @@ -1103,11 +1138,13 @@ def call(self, transaction=None, block_identifier='latest'): block_id = parse_block_identifier(self.web3, block_identifier) return call_contract_function( + hrp, self.web3, self.address, self._return_data_normalizers, self.function_identifier, call_transaction, + self.vmtype, block_id, self.contract_abi, self.abi, @@ -1147,6 +1184,7 @@ def transact(self, transaction=None): transact_transaction, self.contract_abi, self.abi, + self.vmtype, *self.args, **self.kwargs ) @@ -1185,6 +1223,7 @@ def estimateGas(self, transaction=None): estimate_gas_transaction, self.contract_abi, self.abi, + self.vmtype, *self.args, **self.kwargs ) @@ -1224,13 +1263,14 @@ def buildTransaction(self, transaction=None): built_transaction, self.contract_abi, self.abi, + self.vmtype, *self.args, **self.kwargs ) @combomethod def _encode_transaction_data(cls): - return add_0x_prefix(encode_abi(cls.web3, cls.abi, cls.arguments, cls.selector)) + return add_0x_prefix(encode_abi(cls.web3, cls.abi, cls.arguments, cls.vmtype, cls.selector, cls.abi)) _return_data_normalizers = tuple() @@ -1258,6 +1298,7 @@ class ContractEvent: web3 = None contract_abi = None abi = None + vmtype = None def __init__(self, *argument_names): @@ -1282,7 +1323,7 @@ def processReceipt(self, txn_receipt): def _parse_logs(self, txn_receipt): for log in txn_receipt['logs']: try: - decoded_log = get_event_data(self.abi, log) + decoded_log = get_event_data(self.abi, log, self.vmtype) except MismatchedABI: continue yield decoded_log @@ -1333,11 +1374,13 @@ def factory(cls, class_name, **kwargs): def call_contract_function( + hrp, web3, address, normalizers, function_identifier, transaction, + vmtype=None, block_id=None, contract_abi=None, fn_abi=None, @@ -1353,6 +1396,7 @@ def call_contract_function( fn_identifier=function_identifier, contract_abi=contract_abi, fn_abi=fn_abi, + vmtype=vmtype, transaction=transaction, fn_args=args, fn_kwargs=kwargs, @@ -1366,42 +1410,75 @@ def call_contract_function( if fn_abi is None: fn_abi = find_matching_fn_abi(contract_abi, function_identifier, args, kwargs) - output_types = get_abi_output_types(fn_abi) - - try: - output_data = decode_abi(output_types, return_data) - except DecodingError as e: - # Provide a more helpful error message than the one provided by - # eth-abi-utils - is_missing_code_error = ( - return_data in ACCEPTABLE_EMPTY_STRINGS and - web3.eth.getCode(address) in ACCEPTABLE_EMPTY_STRINGS - ) - if is_missing_code_error: - msg = ( - "Could not transact with/call contract function, is contract " - "deployed correctly and chain synced?" + output_types = get_abi_output_types(fn_abi,vmtype) + + if vmtype==1: + # if not isinstance(output_types, list): + # output_types = [output_types] + try: + output_data = wasmdecode_abi(hrp,output_types, return_data, contract_abi) + except DecodingError as e: + # Provide a more helpful error message than the one provided by + # eth-abi-utils + is_missing_code_error = ( + return_data in ACCEPTABLE_EMPTY_STRINGS and + web3.eth.getCode(address) in ACCEPTABLE_EMPTY_STRINGS ) - else: - msg = ( - "Could not decode contract function call {} return data {} for " - "output_types {}".format( - function_identifier, - return_data, - output_types + if is_missing_code_error: + msg = ( + "Could not transact with/call contract function, is contract " + "deployed correctly and chain synced?" + ) + else: + msg = ( + "Could not decode contract function call {} return data {} for " + "output_types {}".format( + function_identifier, + return_data, + output_types + ) ) + raise BadFunctionCallOutput(msg) from e + return output_data + else: + try: + output_data = decode_abi(output_types, return_data) + + except DecodingError as e: + # Provide a more helpful error message than the one provided by + # eth-abi-utils + is_missing_code_error = ( + return_data in ACCEPTABLE_EMPTY_STRINGS and + web3.eth.getCode(address) in ACCEPTABLE_EMPTY_STRINGS ) - raise BadFunctionCallOutput(msg) from e - - _normalizers = itertools.chain( - BASE_RETURN_NORMALIZERS, - normalizers, - ) - normalized_data = map_abi_data(_normalizers, output_types, output_data) + if is_missing_code_error: + msg = ( + "Could not transact with/call contract function, is contract " + "deployed correctly and chain synced?" + ) + else: + msg = ( + "Could not decode contract function call {} return data {} for " + "output_types {}".format( + function_identifier, + return_data, + output_types + ) + ) + raise BadFunctionCallOutput(msg) from e - if len(normalized_data) == 1: - return normalized_data[0] - else: + _normalizers = itertools.chain( + BASE_RETURN_NORMALIZERS, + normalizers, + ) + normalized_data = map_abi_data(_normalizers, output_types, output_data) + # laxdata = [] + for i in range(len(normalized_data)): + if output_types[i] == 'address': + normalized_data[i] = tobech32address(address[:3], normalized_data[i]) + elif output_types[i] == 'address[]': + for j in range(len(normalized_data[i])): + normalized_data[i][j]=tobech32address(address[:3], normalized_data[i][j]) return normalized_data @@ -1434,6 +1511,7 @@ def transact_with_contract_function( transaction=None, contract_abi=None, fn_abi=None, + vmtype=None, *args, **kwargs): """ @@ -1447,6 +1525,7 @@ def transact_with_contract_function( contract_abi=contract_abi, transaction=transaction, fn_abi=fn_abi, + vmtype=vmtype, fn_args=args, fn_kwargs=kwargs, ) @@ -1462,6 +1541,7 @@ def estimate_gas_for_function( transaction=None, contract_abi=None, fn_abi=None, + vmtype=None, *args, **kwargs): """Estimates gas cost a function call would take. @@ -1475,6 +1555,7 @@ def estimate_gas_for_function( fn_identifier=fn_identifier, contract_abi=contract_abi, fn_abi=fn_abi, + vmtype=vmtype, transaction=transaction, fn_args=args, fn_kwargs=kwargs, @@ -1491,6 +1572,7 @@ def build_transaction_for_function( transaction=None, contract_abi=None, fn_abi=None, + vmtype=None, *args, **kwargs): """Builds a dictionary with the fields required to make the given transaction @@ -1504,6 +1586,7 @@ def build_transaction_for_function( fn_identifier=function_name, contract_abi=contract_abi, fn_abi=fn_abi, + vmtype=vmtype, transaction=transaction, fn_args=args, fn_kwargs=kwargs, diff --git a/client_sdk_python/datastructures.py b/client_sdk_python/datastructures.py index 7478c2c..6c18bf6 100644 --- a/client_sdk_python/datastructures.py +++ b/client_sdk_python/datastructures.py @@ -6,7 +6,7 @@ Sequence, ) -from eth_utils import ( +from client_sdk_python.packages.eth_utils import ( is_integer, ) diff --git a/client_sdk_python/debug.py b/client_sdk_python/debug.py index 33ccc1c..e3a71a8 100644 --- a/client_sdk_python/debug.py +++ b/client_sdk_python/debug.py @@ -10,6 +10,7 @@ class Debug(Module): need_analyze = True + need_quota_gas = True def economicConfig(self): return json.loads(self.web3.manager.request_blocking("debug_economicConfig", [])) diff --git a/client_sdk_python/error_code.py b/client_sdk_python/error_code.py new file mode 100644 index 0000000..80f323d --- /dev/null +++ b/client_sdk_python/error_code.py @@ -0,0 +1,114 @@ +RestrictTxPlanSize = 36 +ERROR_INFO = { + # successful error code + 0: 'sendRawTransaction successful', + # System error + 1: 'System error', + # Object not found + 2: 'Object not found', + # Invalid parameter + 3: 'Invalid parameter', + # staking error code + 301000: 'Invalid BLS public key length', + 301001: 'The BLS proof is incorrect', + 301002: 'The Description length is incorrect', + 301003: 'The program version signature is invalid', + 301004: 'The program version is too low', + 301005: 'The Version Declaration is failed when creating staking', + 301006: 'The address must be the same as the one initiated staking', + 301007: 'Invalid param RewardPer', + 301008: 'Modify the commission reward ratio too frequently', + 301009: 'The modification range exceeds the limit', + 301100: 'Staking deposit is insufficient', + 301101: 'The candidate already existed', + 301102: 'The candidate does not exist', + 301103: 'This candidate status is expired', + 301104: 'Increased stake is insufficient', + 301105: 'Delegate deposit is insufficient', + 301106: 'The account is not allowed to delegate', + 301107: 'The candidate is not allowed to delegate', + 301108: 'Withdrawal of delegation is insufficient', + 301109: 'The delegate does not exist', + 301110: 'The von operation type is incorrect', + 301111: 'The account balance is insufficient', + 301112: 'The blockNumber is inconsistent with the expected number', + 301113: 'The balance of delegate is insufficient', + 301114: 'The amount of delegate withdrawal is incorrect', + 301115: 'The validator does not exist', + 301116: 'The fn params is invalid', + 301117: 'The slash type is illegal', + 301118: 'The amount of slash is overflowed', + 301119: 'The amount of slash for decreasing staking is incorrect', + 301200: 'Retreiving verifier list failed', + 301201: 'Retreiving validator list failed', + 301202: 'Retreiving candidate list failed', + 301203: 'Retreiving delegation related mapping failed', + 301204: 'Query candidate info failed', + 301205: 'Query delegate info failed', + 301206: 'Failed to convert Node ID to address', + # government error code + 302001: 'Current active version not found', + 302002: 'Illegal voting option', + 302003: 'Illegal proposal type', + 302004: 'Proposal ID is null', + 302005: 'Proposal ID already existed', + 302006: 'Proposal not found', + 302007: 'PIPID is null', + 302008: 'PIPID already existed', + 302009: 'EndVotingRounds is too small', + 302010: 'EndVotingRounds is too large', + 302011: 'NewVersion should larger than current active version', + 302012: 'Another version proposal already existed at voting stage', + 302013: 'Another version proposal already existed at pre-active stage', + 302014: 'Another cancel proposal already existed at voting stage', + 302015: 'The proposal to be canceled is not found', + 302016: 'The proposal to be canceled proposal has an illegal version type', + 302017: 'The proposal to be canceled is not at voting stage', + 302018: 'The proposer is null', + 302019: 'Detailed verifier information is not found', + 302020: 'The verifier status is invalid', + 302021: 'Transaction account is inconsistent with the staking account', + 302022: 'Transaction node is not the validator', + 302023: 'Transaction node is not the candidate', + 302024: 'Invalid version signature', + 302025: 'Verifier does not upgraded to the latest version', + 302026: 'The proposal is not at voting stage', + 302027: 'Duplicated votes found', + 302028: 'Declared version is invalid', + 302029: 'Error is found when notifying staking for the declared version', + 302030: 'The result of proposal is not found', + 302031: 'Unsupported governent parameter', + 302032: 'Another parameter proposal already existed at voting stage', + 302033: 'Govern parameter value error', + 302034: 'The new value of the parameter proposal is the same as the old one', + # slashing error code + 303000: 'Double-signning verification failed', + 303001: 'Punishment has been executed already', + 303002: 'BlockNumber for the reported double-spending attack is higher than the current value', + 303003: 'Reported evidence expired', + 303004: 'Failed to retrieve the reported validator information', + 303005: 'The evidence address is inconsistent with the validator address', + 303006: 'NodeId does not match', + 303007: 'BlsPubKey does not match', + 303008: 'Slashing node failed', + 303009: 'This node is not a validator', + 303010: "Can't report yourself", + # restricting error code + 304001: 'The initial epoch for staking cannot be zero', + 304002: 'The number of the restricting plan cannot be (0, {}]'.format(RestrictTxPlanSize), + 304003: 'Total staking amount shall be more than 1 LAT', + 304004: 'Create plan,the sender balance is not enough in restrict', + 304005: 'Account is not found on restricting contract', + 304006: 'Slashing amount is larger than staking amount', + 304007: 'Staking amount cannot be 0', + 304008: 'Pledge lock funds amount cannot be less than or equal to 0', + 304009: 'Return lock funds amount cannot be less than or equal to 0', + 304010: 'Slashing amount cannot be less than 0', + 304011: 'Create plan each amount cannot be less than or equal to 0', + 304012: 'The staking amount is less than the return amount', + 304013: 'The user restricting balance is not enough for pledge lock funds', + 304014: 'Create plan each amount should greater than mini amount', + 304015: 'The user restricting and free balance is not enough for pledge lock funds', + # reward error code + 305001: 'Delegation info not found' +} diff --git a/client_sdk_python/eth.py b/client_sdk_python/eth.py index f48735e..52bbc3f 100644 --- a/client_sdk_python/eth.py +++ b/client_sdk_python/eth.py @@ -1,12 +1,13 @@ import json import sha3 import rlp -from eth_utils.hexadecimal import remove_0x_prefix -from platon_account import ( +import copy +from client_sdk_python.packages.eth_utils.hexadecimal import remove_0x_prefix +from client_sdk_python.packages.platon_account import ( Account, ) -from platon_account.internal.transactions import bech32_address_bytes -from eth_utils import ( +from client_sdk_python.packages.platon_account.internal.transactions import bech32_address_bytes +from client_sdk_python.packages.eth_utils import ( apply_to_return_value, is_checksum_address, is_string, @@ -55,10 +56,11 @@ wait_for_transaction_receipt, ) -from platon_account.internal.signing import ( +from client_sdk_python.packages.platon_account.internal.signing import ( to_standard_signature_bytes, ) - +true = True +false = False class Eth(Module): account = Account() defaultAccount = empty @@ -67,6 +69,10 @@ class Eth(Module): iban = Iban gasPriceStrategy = None + def __init__(self, web3): + super().__init__(web3) + self.net_type = self.web3.net_type + @deprecated_for("doing nothing at all") def enable_unaudited_features(self): pass @@ -385,12 +391,57 @@ def uninstallFilter(self, filter_id): return self.web3.manager.request_blocking( "platon_uninstallFilter", [filter_id], ) + def wasm_type(self,abi_data): + for i in range(len(abi_data)): + if abi_data[i]['type']=='Action': + abi_data[i]['type']='function' + if abi_data[i]['type']=='Event': + abi_data[i]['type'] = 'event' + abi_data[i]['anonymous'] = False + if len(abi_data[i]['input']) > 0: + for j in range(len(abi_data[i]['input'])): + abi_data[i]['input'][j]['indexed'] = ((j+1) <= abi_data[i]['topic']) + if abi_data[i]['type'] == 'struct': + if 'fields' in abi_data[i] and 'inputs' not in abi_data[i]: + abi_data[i]['inputs'] = abi_data[i].pop('fields') + if len(abi_data[i]['baseclass'])>0: + for j in range(len(abi_data[i]['baseclass'])): + abi_data[i]['inputs'].insert(j,{'name':abi_data[i]['baseclass'][j],'type':'struct'}) + # else : + # abi_data[i]['inputs'].insert(0, {'name': abi_data[i]['baseclass'], 'type': 'struct'}) + del abi_data[i]['baseclass'] + if abi_data[i]['name']== 'init': + abi_data[i]['type']='constructor' + if 'input' in abi_data[i]: + abi_data[i]['inputs'] = abi_data[i].pop('input') + if 'output' in abi_data[i]: + abi_data[i]['outputs'] = {'name':"",'type':abi_data[i]['output']} + del abi_data[i]['output'] + return abi_data + def contract(self, address=None, **kwargs): + ContractFactoryClass = kwargs.pop('ContractFactoryClass', self.defaultContractFactory) + ContractFactory = ContractFactoryClass.factory(self.web3, **kwargs) + + if address: + return ContractFactory(address) + else: + return ContractFactory + def wasmcontract(self, + address=None, + **kwargs): + if 'vmtype' in kwargs: + if kwargs['vmtype'] == 1: + abi_data=copy.deepcopy(kwargs['abi']) + kwargs['abi']= self.wasm_type(abi_data) + # del kwargs['vmtype'] + ContractFactoryClass = kwargs.pop('ContractFactoryClass', self.defaultContractFactory) + # 若kwargs中有'ContractFactoryClass'这个key,则返回对应的value值,若无这个key,则返回self.defaultContractFactory ContractFactory = ContractFactoryClass.factory(self.web3, **kwargs) if address: @@ -451,4 +502,3 @@ def ecrecover(self, block_identifier): class PlatON(Eth): pass - diff --git a/client_sdk_python/fvnhash.py b/client_sdk_python/fvnhash.py new file mode 100644 index 0000000..adea3c2 --- /dev/null +++ b/client_sdk_python/fvnhash.py @@ -0,0 +1,83 @@ +""" +Implementation of Fowler/Noll/Vo hash algorithm in pure Python. +See http://isthe.com/chongo/tech/comp/fnv/ +""" +from __future__ import absolute_import +from __future__ import division +from __future__ import unicode_literals + +FNV_32_PRIME = 0x01000193 +FNV_64_PRIME = 0x100000001b3 + +FNV0_32_INIT = 0 +FNV0_64_INIT = 0 +FNV1_32_INIT = 0x811c9dc5 +FNV1_32A_INIT = FNV1_32_INIT +FNV1_64_INIT = 0xcbf29ce484222325 +FNV1_64A_INIT = FNV1_64_INIT + +import sys +if sys.version_info[0] == 3: + _get_byte = lambda c: c +else: + _get_byte = ord + +def fnv(data, hval_init, fnv_prime, fnv_size): + """ + Core FNV hash algorithm used in FNV0 and FNV1. + """ + assert isinstance(data, bytes) + + hval = hval_init + for byte in data: + hval = (hval * fnv_prime) % fnv_size + hval = hval ^ _get_byte(byte) + return hval + +def fnva(data, hval_init, fnv_prime, fnv_size): + """ + Alternative FNV hash algorithm used in FNV-1a. + """ + assert isinstance(data, bytes) + + hval = hval_init + for byte in data: + hval = hval ^ _get_byte(byte) + hval = (hval * fnv_prime) % fnv_size + return hval + +def fnv0_32(data, hval_init=FNV0_32_INIT): + """ + Returns the 32 bit FNV-0 hash value for the given data. + """ + return fnv(data, hval_init, FNV_32_PRIME, 2**32) + +def fnv1_32(data, hval_init=FNV1_32_INIT): + """ + Returns the 32 bit FNV-1 hash value for the given data. + """ + return fnv(data, hval_init, FNV_32_PRIME, 2**32) + +def fnv1a_32(data, hval_init=FNV1_32_INIT): + """ + Returns the 32 bit FNV-1a hash value for the given data. + """ + return fnva(data, hval_init, FNV_32_PRIME, 2**32) + +def fnv0_64(data, hval_init=FNV0_64_INIT): + """ + Returns the 64 bit FNV-0 hash value for the given data. + """ + return fnv(data, hval_init, FNV_64_PRIME, 2**64) + +def fnv1_64(data, hval_init=FNV1_64_INIT): + """ + Returns the 64 bit FNV-1 hash value for the given data. + """ + return fnv(data, hval_init, FNV_64_PRIME, 2**64) + +def fnv1a_64(data, hval_init=FNV1_64_INIT): + """ + Returns the 64 bit FNV-1a hash value for the given data. + """ + return fnva(data, hval_init, FNV_64_PRIME, 2**64) \ No newline at end of file diff --git a/client_sdk_python/gas_strategies/time_based.py b/client_sdk_python/gas_strategies/time_based.py index 47fda93..2a7d9bc 100644 --- a/client_sdk_python/gas_strategies/time_based.py +++ b/client_sdk_python/gas_strategies/time_based.py @@ -2,7 +2,7 @@ import math import operator -from eth_utils import ( +from client_sdk_python.packages.eth_utils import ( to_tuple, ) diff --git a/client_sdk_python/iban.py b/client_sdk_python/iban.py index c12f67f..ede982e 100644 --- a/client_sdk_python/iban.py +++ b/client_sdk_python/iban.py @@ -1,7 +1,7 @@ import functools import re -from eth_utils import ( +from client_sdk_python.packages.eth_utils import ( is_string, to_checksum_address, ) diff --git a/client_sdk_python/main.py b/client_sdk_python/main.py index 8eadcb5..c2ab2df 100644 --- a/client_sdk_python/main.py +++ b/client_sdk_python/main.py @@ -1,4 +1,4 @@ -from eth_utils import ( +from client_sdk_python.packages.eth_utils import ( apply_to_return_value, add_0x_prefix, from_wei, @@ -9,9 +9,8 @@ # to_checksum_address, to_wei, ) -from platon_keys.utils.address import MIANNETHRP, TESTNETHRP -from ens import ENS +from client_sdk_python.packages.ens import ENS from client_sdk_python.admin import Admin from client_sdk_python.eth import Eth, PlatON @@ -68,6 +67,7 @@ from client_sdk_python.utils.normalizers import ( abi_ens_resolver, ) +from client_sdk_python.utils.encoding import tobech32address def get_default_modules(): @@ -88,23 +88,14 @@ def get_default_modules(): } -def default_address(mainnet, testnet): - return {MIANNETHRP: mainnet, TESTNETHRP: testnet} - - -restricting = default_address("lat1zqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqp7pn3ep","lax1zqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqp3yp7hw") -staking = default_address("lat1zqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzsjx8h7", "lax1zqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzlh5ge3") -penalty = default_address("lat1zqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqyva9ztf", "lax1zqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqyrchd9x") -pipAddr = default_address("lat1zqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq93t3hkm", "lax1zqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq97wrcc5") -delegateReward = default_address("lat1zqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqxlcypcy", "lax1zqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqxsakwkt") - - def to_checksum_address(val): return val + def is_checksum_address(val): return True + class Web3: # Providers HTTPProvider = HTTPProvider @@ -136,26 +127,31 @@ class Web3: isChecksumAddress = staticmethod(is_checksum_address) toChecksumAddress = staticmethod(to_checksum_address) - def __init__(self, providers=empty, middlewares=None, modules=None, ens=empty, chain_id=100): + def __init__(self, providers=empty, middlewares=None, modules=None, ens=empty, chain_id=100, hrp_type=None): self.manager = RequestManager(self, providers, middlewares) - + if providers: + try: + self.net_type = self.getAddressHrp + except Exception as e: + if not hrp_type: + raise ValueError( + "Failed to obtain hrp automatically,need to be passed in from outside,exception info:{}".format(e) + ) + else: + self.net_type = hrp_type + else: + if not hrp_type: + raise ValueError( + "Offline mode needs to specify the network type and cannot be empty,parameter hrp_type must be specified" + ) + self.net_type = hrp_type if modules is None: modules = get_default_modules() for module_name, module_class in modules.items(): module_class.attach(self, module_name) - if chain_id == 100: - self.net_type = MIANNETHRP - else: - self.net_type = TESTNETHRP # platon contract address - self.restrictingAddress = restricting[self.net_type] - self.stakingAddress = staking[self.net_type] - self.penaltyAddress = penalty[self.net_type] - self.pipAddress = pipAddr[self.net_type] - self.delegateRewardAddress = delegateReward[self.net_type] - self.ens = ens self.chain_id = chain_id @@ -236,11 +232,13 @@ def ens(self): else: return self._ens + @property + def getAddressHrp(self): + return self.manager.request_blocking("platon_getAddressHrp", []) + @ens.setter def ens(self, new_ens): self._ens = new_ens def pubkey_to_address(self, pubkey): - addr_dict = {MIANNETHRP: pubkey.to_bech32_address(), - TESTNETHRP: pubkey.to_bech32_test_address()} - return addr_dict[self.net_type] + return pubkey.to_bech32_address(self.net_type) diff --git a/client_sdk_python/manager.py b/client_sdk_python/manager.py index 20d9019..999aa6e 100644 --- a/client_sdk_python/manager.py +++ b/client_sdk_python/manager.py @@ -1,7 +1,7 @@ import logging import uuid -from eth_utils import ( +from client_sdk_python.packages.eth_utils import ( is_list_like, ) diff --git a/client_sdk_python/middleware/attrdict.py b/client_sdk_python/middleware/attrdict.py index b917267..6780855 100644 --- a/client_sdk_python/middleware/attrdict.py +++ b/client_sdk_python/middleware/attrdict.py @@ -1,4 +1,4 @@ -from eth_utils import ( +from client_sdk_python.packages.eth_utils import ( is_dict, ) diff --git a/client_sdk_python/middleware/geth_poa.py b/client_sdk_python/middleware/geth_poa.py index 5e02873..3204b4e 100644 --- a/client_sdk_python/middleware/geth_poa.py +++ b/client_sdk_python/middleware/geth_poa.py @@ -1,4 +1,4 @@ -from eth_utils.curried import ( +from client_sdk_python.packages.eth_utils.curried import ( apply_formatters_to_dict, apply_key_map, ) diff --git a/client_sdk_python/middleware/normalize_request_parameters.py b/client_sdk_python/middleware/normalize_request_parameters.py index df1763e..e82c429 100644 --- a/client_sdk_python/middleware/normalize_request_parameters.py +++ b/client_sdk_python/middleware/normalize_request_parameters.py @@ -1,4 +1,4 @@ -from eth_utils import ( +from client_sdk_python.packages.eth_utils import ( is_string, ) diff --git a/client_sdk_python/middleware/pythonic.py b/client_sdk_python/middleware/pythonic.py index dba5348..663f388 100644 --- a/client_sdk_python/middleware/pythonic.py +++ b/client_sdk_python/middleware/pythonic.py @@ -1,7 +1,7 @@ import codecs import operator -from eth_utils.curried import ( +from client_sdk_python.packages.eth_utils.curried import ( combine_argument_formatters, is_address, is_bytes, @@ -67,6 +67,15 @@ def to_checksum_address(val): return val +@curry +def spacial_to_hexbytes(val): + if isinstance(val, (str, int, bytes)): + result = HexBytes(val) + else: + raise TypeError("Cannot convert %r to HexBytes" % val) + return result + + @curry def to_hexbytes(num_bytes, val, variable_length=False): if isinstance(val, (str, int, bytes)): @@ -155,7 +164,7 @@ def to_hexbytes(num_bytes, val, variable_length=False): receipt_formatter = apply_formatters_to_dict(RECEIPT_FORMATTERS) BLOCK_FORMATTERS = { - 'extraData': to_hexbytes(32, variable_length=True), + 'extraData': spacial_to_hexbytes(), 'gasLimit': to_integer_if_hex, 'gasUsed': to_integer_if_hex, 'size': to_integer_if_hex, diff --git a/client_sdk_python/middleware/signing.py b/client_sdk_python/middleware/signing.py index 48e9ef8..19462aa 100644 --- a/client_sdk_python/middleware/signing.py +++ b/client_sdk_python/middleware/signing.py @@ -3,16 +3,16 @@ ) import operator -from platon_account import ( +from client_sdk_python.packages.platon_account import ( Account, ) -from platon_account.local import ( +from client_sdk_python.packages.platon_account.local import ( LocalAccount, ) -from platon_keys.datatypes import ( +from client_sdk_python.packages.platon_keys.datatypes import ( PrivateKey, ) -from eth_utils import ( +from client_sdk_python.packages.eth_utils import ( to_dict, ) diff --git a/client_sdk_python/middleware/validation.py b/client_sdk_python/middleware/validation.py index 983faec..1c66ee1 100644 --- a/client_sdk_python/middleware/validation.py +++ b/client_sdk_python/middleware/validation.py @@ -1,4 +1,4 @@ -from eth_utils.curried import ( +from client_sdk_python.packages.eth_utils.curried import ( apply_formatter_at_index, apply_formatter_if, apply_formatters_to_dict, @@ -42,20 +42,21 @@ def validate_chain_id(web3, chain_id): def check_extradata_length(val): - if not isinstance(val, (str, int, bytes)): - return val - result = HexBytes(val) - if len(result) > MAX_EXTRADATA_LENGTH: - raise ValidationError( - "The field extraData is %d bytes, but should be %d. " - "It is quite likely that you are connected to a POA chain. " - "Refer " - "http://web3py.readthedocs.io/en/stable/middleware.html#geth-style-proof-of-authority " - "for more details. The full extraData is: %r" % ( - len(result), MAX_EXTRADATA_LENGTH, result - ) - ) return val + # if not isinstance(val, (str, int, bytes)): + # return val + # result = HexBytes(val) + # if len(result) > MAX_EXTRADATA_LENGTH: + # raise ValidationError( + # "The field extraData is %d bytes, but should be %d. " + # "It is quite likely that you are connected to a POA chain. " + # "Refer " + # "http://web3py.readthedocs.io/en/stable/middleware.html#geth-style-proof-of-authority " + # "for more details. The full extraData is: %r" % ( + # len(result), MAX_EXTRADATA_LENGTH, result + # ) + # ) + # return val def transaction_normalizer(transaction): diff --git a/client_sdk_python/packages/__init__.py b/client_sdk_python/packages/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/ens/__init__.py b/client_sdk_python/packages/ens/__init__.py similarity index 100% rename from ens/__init__.py rename to client_sdk_python/packages/ens/__init__.py diff --git a/ens/abis.py b/client_sdk_python/packages/ens/abis.py similarity index 100% rename from ens/abis.py rename to client_sdk_python/packages/ens/abis.py diff --git a/client_sdk_python/packages/ens/auto.py b/client_sdk_python/packages/ens/auto.py new file mode 100644 index 0000000..4c52bed --- /dev/null +++ b/client_sdk_python/packages/ens/auto.py @@ -0,0 +1,3 @@ +from client_sdk_python.packages.ens import ENS + +ns = ENS() diff --git a/ens/constants.py b/client_sdk_python/packages/ens/constants.py similarity index 100% rename from ens/constants.py rename to client_sdk_python/packages/ens/constants.py diff --git a/ens/contract_data.py b/client_sdk_python/packages/ens/contract_data.py similarity index 100% rename from ens/contract_data.py rename to client_sdk_python/packages/ens/contract_data.py diff --git a/ens/exceptions.py b/client_sdk_python/packages/ens/exceptions.py similarity index 100% rename from ens/exceptions.py rename to client_sdk_python/packages/ens/exceptions.py diff --git a/ens/main.py b/client_sdk_python/packages/ens/main.py similarity index 97% rename from ens/main.py rename to client_sdk_python/packages/ens/main.py index da2b742..4bebaa7 100644 --- a/ens/main.py +++ b/client_sdk_python/packages/ens/main.py @@ -1,21 +1,21 @@ -from eth_utils import ( +from client_sdk_python.packages.eth_utils import ( is_binary_address, is_checksum_address, to_checksum_address, ) -from ens import abis -from ens.constants import ( +from client_sdk_python.packages.ens import abis +from client_sdk_python.packages.ens.constants import ( EMPTY_ADDR_HEX, REVERSE_REGISTRAR_DOMAIN, ) -from ens.exceptions import ( +from client_sdk_python.packages.ens.exceptions import ( AddressMismatch, UnauthorizedError, UnownedName, ) -from ens.utils import ( +from client_sdk_python.packages.ens.utils import ( address_in, address_to_reverse_domain, default, diff --git a/ens/utils.py b/client_sdk_python/packages/ens/utils.py similarity index 97% rename from ens/utils.py rename to client_sdk_python/packages/ens/utils.py index 28d0c27..cd75921 100644 --- a/ens/utils.py +++ b/client_sdk_python/packages/ens/utils.py @@ -3,14 +3,14 @@ import datetime import functools -from eth_utils import ( +from client_sdk_python.packages.eth_utils import ( is_same_address, remove_0x_prefix, to_normalized_address, ) import idna -from ens.constants import ( +from client_sdk_python.packages.ens.constants import ( ACCEPTABLE_STALE_HOURS, AUCTION_START_GAS_CONSTANT, AUCTION_START_GAS_MARGINAL, @@ -19,7 +19,7 @@ RECOGNIZED_TLDS, REVERSE_REGISTRAR_DOMAIN, ) -from ens.exceptions import ( +from client_sdk_python.packages.ens.exceptions import ( InvalidLabel, InvalidName, ) diff --git a/client_sdk_python/packages/eth_abi/__init__.py b/client_sdk_python/packages/eth_abi/__init__.py new file mode 100644 index 0000000..c0c0c0d --- /dev/null +++ b/client_sdk_python/packages/eth_abi/__init__.py @@ -0,0 +1,9 @@ +import pkg_resources + +from client_sdk_python.packages.eth_abi.abi import ( + decode_single, + decode_abi, + encode_single, + encode_abi, + is_encodable, +) \ No newline at end of file diff --git a/client_sdk_python/packages/eth_abi/abi.py b/client_sdk_python/packages/eth_abi/abi.py new file mode 100644 index 0000000..5fdc1d2 --- /dev/null +++ b/client_sdk_python/packages/eth_abi/abi.py @@ -0,0 +1,98 @@ +""" +Vendored from `pyethereum.abi` +""" +from client_sdk_python.packages.eth_utils import ( + is_bytes, +) + +from client_sdk_python.packages.eth_abi.decoding import ( + ContextFramesBytesIO, + TupleDecoder, +) + +from client_sdk_python.packages.eth_abi.exceptions import EncodingError + +from client_sdk_python.packages.eth_abi.encoding import TupleEncoder + +from client_sdk_python.packages.eth_abi.registry import registry + +from client_sdk_python.packages.eth_abi.utils.parsing import ( # noqa: F401 + process_type, + collapse_type, +) + +def encode_single(typ, arg): + if isinstance(typ, str): + type_str = typ + else: + type_str = collapse_type(*typ) + + encoder = registry.get_encoder(type_str) + + return encoder(arg) + + +def encode_abi(types, args): + encoders = [ + registry.get_encoder(type_str) + for type_str in types + ] + + encoder = TupleEncoder(encoders=encoders) + + return encoder(args) + + +def is_encodable(typ, arg): + """ + Determines if the given python value ``arg`` can be encoded as a value of + abi type ``typ``. + """ + if isinstance(typ, str): + type_str = typ + else: + type_str = collapse_type(*typ) + + encoder = registry.get_encoder(type_str) + + try: + encoder.validate_value(arg) + except EncodingError: + return False + else: + return True + + +# Decodes a single base datum +def decode_single(typ, data): + if not is_bytes(data): + raise TypeError("The `data` value must be of bytes type. Got {0}".format(type(data))) + + if isinstance(typ, str): + type_str = typ + else: + type_str = collapse_type(*typ) + + decoder = registry.get_decoder(type_str) + stream = ContextFramesBytesIO(data) + + return decoder(stream) + + +# Decodes multiple arguments using the head/tail mechanism +def decode_abi(types, data): + if not is_bytes(data): + raise TypeError("The `data` value must be of bytes type. Got {0}".format(type(data))) + + decoders = [ + registry.get_decoder(type_str) + for type_str in types + ] + + decoder = TupleDecoder(decoders=decoders) + stream = ContextFramesBytesIO(data) + + return decoder(stream) + + + diff --git a/client_sdk_python/packages/eth_abi/base.py b/client_sdk_python/packages/eth_abi/base.py new file mode 100644 index 0000000..fbe835d --- /dev/null +++ b/client_sdk_python/packages/eth_abi/base.py @@ -0,0 +1,147 @@ +import functools + +from .grammar import ( + BasicType, + TupleType, + normalize, + parse, +) + + +def parse_type_str(expected_base=None, with_arrlist=False): + """ + Used by BaseCoder subclasses as a convenience for implementing the + ``from_type_str`` method required by ``ABIRegistry``. Useful if normalizing + then parsing a type string with an (optional) expected base is required in + that method. + """ + def decorator(old_from_type_str): + @functools.wraps(old_from_type_str) + def new_from_type_str(cls, type_str, registry): + normalized_type_str = normalize(type_str) + abi_type = parse(normalized_type_str) + + type_str_repr = repr(type_str) + if type_str != normalized_type_str: + type_str_repr = '{} (normalized to {})'.format( + type_str_repr, + repr(normalized_type_str), + ) + + if expected_base is not None: + if not isinstance(abi_type, BasicType): + raise ValueError( + 'Cannot create {} for non-basic type {}'.format( + cls.__name__, + type_str_repr, + ) + ) + if abi_type.base != expected_base: + raise ValueError( + 'Cannot create {} for type {}: expected type with ' + "base '{}'".format( + cls.__name__, + type_str_repr, + expected_base, + ) + ) + + if not with_arrlist and abi_type.arrlist is not None: + raise ValueError( + 'Cannot create {} for type {}: expected type with ' + 'no array dimension list'.format( + cls.__name__, + type_str_repr, + ) + ) + if with_arrlist and abi_type.arrlist is None: + raise ValueError( + 'Cannot create {} for type {}: expected type with ' + 'array dimension list'.format( + cls.__name__, + type_str_repr, + ) + ) + + # Perform general validation of default solidity types + abi_type.validate() + + return old_from_type_str(cls, abi_type, registry) + + return classmethod(new_from_type_str) + + return decorator + + +def parse_tuple_type_str(old_from_type_str): + """ + Used by BaseCoder subclasses as a convenience for implementing the + ``from_type_str`` method required by ``ABIRegistry``. Useful if normalizing + then parsing a tuple type string is required in that method. + """ + @functools.wraps(old_from_type_str) + def new_from_type_str(cls, type_str, registry): + normalized_type_str = normalize(type_str) + abi_type = parse(normalized_type_str) + + type_str_repr = repr(type_str) + if type_str != normalized_type_str: + type_str_repr = '{} (normalized to {})'.format( + type_str_repr, + repr(normalized_type_str), + ) + + if not isinstance(abi_type, TupleType): + raise ValueError( + 'Cannot create {} for non-tuple type {}'.format( + cls.__name__, + type_str_repr, + ) + ) + + abi_type.validate() + + return old_from_type_str(cls, abi_type, registry) + + return classmethod(new_from_type_str) + + +class BaseCoder: + is_dynamic = False + + def __init__(self, **kwargs): + """ + Creates an encoder or decoder with the given settings kwargs. + """ + cls = type(self) + + # Ensure no unrecognized kwargs were given + for key, value in kwargs.items(): + if not hasattr(cls, key): + raise AttributeError( + 'Property {key} not found on {cls_name} class. ' + '`{cls_name}.__init__` only accepts keyword arguments which are ' + 'present on the {cls_name} class.'.format( + key=key, + cls_name=cls.__name__, + ) + ) + setattr(self, key, value) + + # Validate given combination of kwargs + self.validate() + + def validate(self): + """ + Validates that an encoder's or decoder's settings are valid in + combination. + """ + pass + + @classmethod + def from_type_str(cls, type_str, registry): # pragma: no cover + """ + Used by ``ABIRegistry`` to get an appropriate encoder or decoder + instance for the given type string and type registry. + """ + raise NotImplementedError('Must implement `from_type_str`') diff --git a/client_sdk_python/packages/eth_abi/constants.py b/client_sdk_python/packages/eth_abi/constants.py new file mode 100644 index 0000000..45b1b36 --- /dev/null +++ b/client_sdk_python/packages/eth_abi/constants.py @@ -0,0 +1,3 @@ +TT256 = 2 ** 256 +TT256M1 = 2 ** 256 - 1 +TT255 = 2 ** 255 diff --git a/client_sdk_python/packages/eth_abi/decoding.py b/client_sdk_python/packages/eth_abi/decoding.py new file mode 100644 index 0000000..fe8670d --- /dev/null +++ b/client_sdk_python/packages/eth_abi/decoding.py @@ -0,0 +1,613 @@ +import abc +import decimal +import io + +from client_sdk_python.packages.eth_utils import ( + big_endian_to_int, + to_tuple, + to_normalized_address, +) + +from client_sdk_python.packages.eth_abi.base import ( + BaseCoder, + parse_type_str, + parse_tuple_type_str, +) + +from client_sdk_python.packages.eth_abi.exceptions import ( + InsufficientDataBytes, + NonEmptyPaddingBytes, +) + +from client_sdk_python.packages.eth_abi.utils.numeric import ( + TEN, + abi_decimal_context, + ceil32, + quantize_value, +) + + +class ContextFramesBytesIO(io.BytesIO): + """ + A byte stream which can track a series of contextual frames in a stack. This + data structure is necessary to perform nested decodings using the + ``HeadTailDecoder`` since offsets present in head sections are relative only + to a particular encoded object. These offsets can only be used to locate a + position in a decoding stream if they are paired with a contextual offset + that establishes the position of the object in which they are found. + + For example, consider the encoding of a value for the following type: + + type: (int,(int,int[])) + value: (1,(2,[3,3])) + + There are two tuples in this type: one inner and one outer. The inner tuple + type contains a dynamic type `int[]` and, therefore, is itself dynamic. + This means that its value encoding will be placed in the tail section of the + outer tuple's encoding. Furthermore, the inner tuple's encoding will, + itself, contain a tail section with the encoding for `[3,3]`. All together, + the encoded value of `(1,(2,[3,3]))` would look like this (the data values + are normally 32 bytes wide but have been truncated to remove the redundant + zeros at the beginnings of their encodings): + + offset data + -------------------------- + ^ 0 0x01 + | 32 0x40 <-- Offset of object A in global frame (64) + -----|-------------------- + Global frame ^ 64 0x02 <-- Beginning of object A (64 w/offset 0 = 64) + | | 96 0x40 <-- Offset of object B in frame of object A (64) + -----|-Object A's frame--- + | | 128 0x02 <-- Beginning of object B (64 w/offset 64 = 128) + | | 160 0x03 + v v 192 0x03 + -------------------------- + + Note that the offset of object B is encoded as 64 which only specifies the + beginning of its encoded value relative to the beginning of object A's + encoding. Globally, object B is located at offset 128. In order to make + sense out of object B's offset, it needs to be positioned in the context of + its enclosing object's frame (object A). + """ + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + self._frames = [] + self._total_offset = 0 + + def seek_in_frame(self, pos, *args, **kwargs): + """ + Seeks relative to the total offset of the current contextual frames. + """ + super().seek(self._total_offset + pos, *args, **kwargs) + + def push_frame(self, offset): + """ + Pushes a new contextual frame onto the stack with the given offset and a + return position at the current cursor position then seeks to the new + total offset. + """ + self._frames.append((offset, self.tell())) + self._total_offset += offset + + self.seek_in_frame(0) + + def pop_frame(self): + """ + Pops the current contextual frame off of the stack and returns the + cursor to the frame's return position. + """ + try: + offset, return_pos = self._frames.pop() + except IndexError: + raise IndexError('no frames to pop') + self._total_offset -= offset + + self.seek(return_pos) + + +class BaseDecoder(BaseCoder, metaclass=abc.ABCMeta): + @abc.abstractmethod + def decode(self, stream): # pragma: no cover + """ + Decodes the given stream of bytes into a Python value. + """ + pass + + def __call__(self, stream): + return self.decode(stream) + + +class HeadTailDecoder(BaseDecoder): + is_dynamic = True + + tail_decoder = None + + def validate(self): + super().validate() + + if self.tail_decoder is None: + raise ValueError("No `tail_decoder` set") + + def decode(self, stream): + start_pos = decode_uint_256(stream) + + stream.push_frame(start_pos) + value = self.tail_decoder(stream) + stream.pop_frame() + + return value + + +class TupleDecoder(BaseDecoder): + decoders = None + + def __init__(self, **kwargs): + super().__init__(**kwargs) + + self.decoders = tuple( + HeadTailDecoder(tail_decoder=d) if d.is_dynamic else d + for d in self.decoders + ) + + self.is_dynamic = any(d.is_dynamic for d in self.decoders) + + def validate(self): + super().validate() + + if self.decoders is None: + raise ValueError("No `decoders` set") + + @to_tuple + def decode(self, stream): + for decoder in self.decoders: + yield decoder(stream) + + @parse_tuple_type_str + def from_type_str(cls, abi_type, registry): + decoders = tuple(registry.get_decoder(str(c)) for c in abi_type.components) + + return cls(decoders=decoders) + + +class SingleDecoder(BaseDecoder): + decoder_fn = None + + def validate(self): + super().validate() + + if self.decoder_fn is None: + raise ValueError("No `decoder_fn` set") + + def validate_padding_bytes(self, value, padding_bytes): + raise NotImplementedError("Must be implemented by subclasses") + + def decode(self, stream): + raw_data = self.read_data_from_stream(stream) + data, padding_bytes = self.split_data_and_padding(raw_data) + value = self.decoder_fn(data) + self.validate_padding_bytes(value, padding_bytes) + + return value + + def read_data_from_stream(self, stream): + raise NotImplementedError("Must be implemented by subclasses") + + def split_data_and_padding(self, raw_data): + return raw_data, b'' + + +class BaseArrayDecoder(BaseDecoder): + item_decoder = None + + def __init__(self, **kwargs): + super().__init__(**kwargs) + + # Use a head-tail decoder to decode dynamic elements + if self.item_decoder.is_dynamic: + self.item_decoder = HeadTailDecoder( + tail_decoder=self.item_decoder, + ) + + def validate(self): + super().validate() + + if self.item_decoder is None: + raise ValueError("No `item_decoder` set") + + @parse_type_str(with_arrlist=True) + def from_type_str(cls, abi_type, registry): + item_decoder = registry.get_decoder(str(abi_type.item_type)) + + array_spec = abi_type.arrlist[-1] + if len(array_spec) == 1: + # If array dimension is fixed + return SizedArrayDecoder( + array_size=array_spec[0], + item_decoder=item_decoder, + ) + else: + # If array dimension is dynamic + return DynamicArrayDecoder(item_decoder=item_decoder) + + +class SizedArrayDecoder(BaseArrayDecoder): + array_size = None + + def __init__(self, **kwargs): + super().__init__(**kwargs) + + self.is_dynamic = self.item_decoder.is_dynamic + + @to_tuple + def decode(self, stream): + for _ in range(self.array_size): + yield self.item_decoder(stream) + + +class DynamicArrayDecoder(BaseArrayDecoder): + # Dynamic arrays are always dynamic, regardless of their elements + is_dynamic = True + + @to_tuple + def decode(self, stream): + array_size = decode_uint_256(stream) + stream.push_frame(32) + for _ in range(array_size): + yield self.item_decoder(stream) + stream.pop_frame() + + +class FixedByteSizeDecoder(SingleDecoder): + decoder_fn = None + value_bit_size = None + data_byte_size = None + is_big_endian = None + + def validate(self): + super().validate() + + if self.value_bit_size is None: + raise ValueError("`value_bit_size` may not be None") + if self.data_byte_size is None: + raise ValueError("`data_byte_size` may not be None") + if self.decoder_fn is None: + raise ValueError("`decoder_fn` may not be None") + if self.is_big_endian is None: + raise ValueError("`is_big_endian` may not be None") + + if self.value_bit_size % 8 != 0: + raise ValueError( + "Invalid value bit size: {0}. Must be a multiple of 8".format( + self.value_bit_size, + ) + ) + + if self.value_bit_size > self.data_byte_size * 8: + raise ValueError("Value byte size exceeds data size") + + def read_data_from_stream(self, stream): + data = stream.read(self.data_byte_size) + + if len(data) != self.data_byte_size: + raise InsufficientDataBytes( + "Tried to read {0} bytes. Only got {1} bytes".format( + self.data_byte_size, + len(data), + ) + ) + + return data + + def split_data_and_padding(self, raw_data): + value_byte_size = self._get_value_byte_size() + padding_size = self.data_byte_size - value_byte_size + + if self.is_big_endian: + padding_bytes = raw_data[:padding_size] + data = raw_data[padding_size:] + else: + data = raw_data[:value_byte_size] + padding_bytes = raw_data[value_byte_size:] + + return data, padding_bytes + + def validate_padding_bytes(self, value, padding_bytes): + value_byte_size = self._get_value_byte_size() + padding_size = self.data_byte_size - value_byte_size + + if padding_bytes != b'\x00' * padding_size: + raise NonEmptyPaddingBytes( + "Padding bytes were not empty: {0}".format(repr(padding_bytes)) + ) + + def _get_value_byte_size(self): + value_byte_size = self.value_bit_size // 8 + return value_byte_size + + +class Fixed32ByteSizeDecoder(FixedByteSizeDecoder): + data_byte_size = 32 + + +class BooleanDecoder(Fixed32ByteSizeDecoder): + value_bit_size = 8 + is_big_endian = True + + @staticmethod + def decoder_fn(data): + if data == b'\x00': + return False + elif data == b'\x01': + return True + else: + raise NonEmptyPaddingBytes( + "Boolean must be either 0x0 or 0x1. Got: {0}".format(repr(data)) + ) + + @parse_type_str('bool') + def from_type_str(cls, abi_type, registry): + return cls() + + +class AddressDecoder(Fixed32ByteSizeDecoder): + value_bit_size = 20 * 8 + is_big_endian = True + decoder_fn = staticmethod(to_normalized_address) + + @parse_type_str('address') + def from_type_str(cls, abi_type, registry): + return cls() + + +# +# Unsigned Integer Decoders +# +class UnsignedIntegerDecoder(Fixed32ByteSizeDecoder): + decoder_fn = staticmethod(big_endian_to_int) + is_big_endian = True + + @parse_type_str('uint') + def from_type_str(cls, abi_type, registry): + return cls(value_bit_size=abi_type.sub) + + +decode_uint_256 = UnsignedIntegerDecoder(value_bit_size=256) + + +# +# Signed Integer Decoders +# +class SignedIntegerDecoder(Fixed32ByteSizeDecoder): + is_big_endian = True + + def decoder_fn(self, data): + value = big_endian_to_int(data) + if value >= 2 ** (self.value_bit_size - 1): + return value - 2 ** self.value_bit_size + else: + return value + + def validate_padding_bytes(self, value, padding_bytes): + value_byte_size = self._get_value_byte_size() + padding_size = self.data_byte_size - value_byte_size + + if value >= 0: + expected_padding_bytes = b'\x00' * padding_size + else: + expected_padding_bytes = b'\xff' * padding_size + + if padding_bytes != expected_padding_bytes: + raise NonEmptyPaddingBytes( + "Padding bytes were not empty: {0}".format(repr(padding_bytes)) + ) + + @parse_type_str('int') + def from_type_str(cls, abi_type, registry): + return cls(value_bit_size=abi_type.sub) + + +# +# Bytes1..32 +# +class BytesDecoder(Fixed32ByteSizeDecoder): + is_big_endian = False + + @staticmethod + def decoder_fn(data): + return data + + @parse_type_str('bytes') + def from_type_str(cls, abi_type, registry): + return cls(value_bit_size=abi_type.sub * 8) + + +class BaseFixedDecoder(Fixed32ByteSizeDecoder): + frac_places = None + is_big_endian = True + + def validate(self): + super().validate() + + if self.frac_places is None: + raise ValueError("must specify `frac_places`") + + if self.frac_places <= 0 or self.frac_places > 80: + raise ValueError("`frac_places` must be in range (0, 80]") + + +class UnsignedFixedDecoder(BaseFixedDecoder): + def decoder_fn(self, data): + value = big_endian_to_int(data) + + with decimal.localcontext(abi_decimal_context): + decimal_value = decimal.Decimal(value) / TEN ** self.frac_places + + return decimal_value + + @parse_type_str('ufixed') + def from_type_str(cls, abi_type, registry): + value_bit_size, frac_places = abi_type.sub + + return cls(value_bit_size=value_bit_size, frac_places=frac_places) + + +class SignedFixedDecoder(BaseFixedDecoder): + def decoder_fn(self, data): + value = big_endian_to_int(data) + if value >= 2 ** (self.value_bit_size - 1): + signed_value = value - 2 ** self.value_bit_size + else: + signed_value = value + + with decimal.localcontext(abi_decimal_context): + decimal_value = decimal.Decimal(signed_value) / TEN ** self.frac_places + + return decimal_value + + def validate_padding_bytes(self, value, padding_bytes): + value_byte_size = self._get_value_byte_size() + padding_size = self.data_byte_size - value_byte_size + + if value >= 0: + expected_padding_bytes = b'\x00' * padding_size + else: + expected_padding_bytes = b'\xff' * padding_size + + if padding_bytes != expected_padding_bytes: + raise NonEmptyPaddingBytes( + "Padding bytes were not empty: {0}".format(repr(padding_bytes)) + ) + + @parse_type_str('fixed') + def from_type_str(cls, abi_type, registry): + value_bit_size, frac_places = abi_type.sub + + return cls(value_bit_size=value_bit_size, frac_places=frac_places) + + +class BaseRealDecoder(Fixed32ByteSizeDecoder): + high_bit_size = None + low_bit_size = None + is_big_endian = True + + def validate(self): + super().validate() + + if self.high_bit_size is None: + raise ValueError("`high_bit_size` cannot be null") + if self.low_bit_size is None: + raise ValueError("`low_bit_size` cannot be null") + if self.low_bit_size + self.high_bit_size != self.value_bit_size: + raise ValueError("high and low bitsizes must sum to the value_bit_size") + + +class UnsignedRealDecoder(BaseRealDecoder): + def decoder_fn(self, data): + value = big_endian_to_int(data) + + with decimal.localcontext(abi_decimal_context): + decimal_value = decimal.Decimal(value) + raw_real_value = decimal_value / 2 ** self.low_bit_size + real_value = quantize_value(raw_real_value, self.low_bit_size) + + return real_value + + @parse_type_str('ureal') + def from_type_str(cls, abi_type, registry): + high_bit_size, low_bit_size = abi_type.sub + + return cls( + value_bit_size=high_bit_size + low_bit_size, + high_bit_size=high_bit_size, + low_bit_size=low_bit_size, + ) + + +class SignedRealDecoder(BaseRealDecoder): + def decoder_fn(self, data): + value = big_endian_to_int(data) + + if value >= 2 ** (self.high_bit_size + self.low_bit_size - 1): + signed_value = value - 2 ** (self.high_bit_size + self.low_bit_size) + else: + signed_value = value + + with decimal.localcontext(abi_decimal_context): + signed_decimal_value = decimal.Decimal(signed_value) + raw_real_value = signed_decimal_value / 2 ** self.low_bit_size + real_value = quantize_value(raw_real_value, self.low_bit_size) + + return real_value + + def validate_padding_bytes(self, value, padding_bytes): + value_byte_size = self._get_value_byte_size() + padding_size = self.data_byte_size - value_byte_size + + if value >= 0: + expected_padding_bytes = b'\x00' * padding_size + else: + expected_padding_bytes = b'\xff' * padding_size + + if padding_bytes != expected_padding_bytes: + raise NonEmptyPaddingBytes( + "Padding bytes were not empty: {0}".format(repr(padding_bytes)) + ) + + @parse_type_str('real') + def from_type_str(cls, abi_type, registry): + high_bit_size, low_bit_size = abi_type.sub + + return cls( + value_bit_size=high_bit_size + low_bit_size, + high_bit_size=high_bit_size, + low_bit_size=low_bit_size, + ) + + +# +# String and Bytes +# +class StringDecoder(SingleDecoder): + is_dynamic = True + + @staticmethod + def decoder_fn(data): + return data + + @staticmethod + def read_data_from_stream(stream): + data_length = decode_uint_256(stream) + padded_length = ceil32(data_length) + + data = stream.read(padded_length) + + if len(data) < padded_length: + raise InsufficientDataBytes( + "Tried to read {0} bytes. Only got {1} bytes".format( + padded_length, + len(data), + ) + ) + + padding_bytes = data[data_length:] + + if padding_bytes != b'\x00' * (padded_length - data_length): + raise NonEmptyPaddingBytes( + "Padding bytes were not empty: {0}".format(repr(padding_bytes)) + ) + + return data[:data_length] + + def validate_padding_bytes(self, value, padding_bytes): + pass + + @parse_type_str('string') + def from_type_str(cls, abi_type, registry): + return cls() + + +class ByteStringDecoder(StringDecoder): + @parse_type_str('bytes') + def from_type_str(cls, abi_type, registry): + return cls() diff --git a/client_sdk_python/packages/eth_abi/encoding.py b/client_sdk_python/packages/eth_abi/encoding.py new file mode 100644 index 0000000..e017d85 --- /dev/null +++ b/client_sdk_python/packages/eth_abi/encoding.py @@ -0,0 +1,669 @@ +from itertools import accumulate +import abc +import codecs +import decimal + +from client_sdk_python.packages.eth_utils import ( + int_to_big_endian, + is_boolean, + is_integer, + is_number, + is_address, + is_bytes, + is_text, + is_list_like, + to_canonical_address, +) + +from client_sdk_python.packages.eth_abi.base import ( + BaseCoder, + parse_type_str, + parse_tuple_type_str, +) + +from client_sdk_python.packages.eth_abi.exceptions import ( + EncodingTypeError, + IllegalValue, + ValueOutOfBounds, +) + +from client_sdk_python.packages.eth_abi.utils.numeric import ( + TEN, + abi_decimal_context, + compute_signed_integer_bounds, + compute_unsigned_integer_bounds, + compute_signed_fixed_bounds, + compute_unsigned_fixed_bounds, + compute_signed_real_bounds, + compute_unsigned_real_bounds, + ceil32, +) +from client_sdk_python.packages.eth_abi.utils.padding import ( + fpad, + zpad, + zpad_right, +) + + +class BaseEncoder(BaseCoder, metaclass=abc.ABCMeta): + @abc.abstractmethod + def encode(self, value): # pragma: no cover + """ + Encodes the given Python value as a sequence of bytes. + """ + pass + + @abc.abstractmethod + def validate_value(self, value): + """ + Determines whether or not the given value can be encoded by this + encoder. + """ + pass + + def __call__(self, value): + return self.encode(value) + + +class TupleEncoder(BaseEncoder): + encoders = None + + def __init__(self, **kwargs): + super().__init__(**kwargs) + + self.is_dynamic = any(e.is_dynamic for e in self.encoders) + + def validate(self): + super().validate() + + if self.encoders is None: + raise ValueError("`encoders` may not be none") + + def validate_value(self, value): + if not is_list_like(value): + raise EncodingTypeError( + "Cannot encode value of type {0} using tuple encoder. Must be " + "a list-like object such as an array or tuple".format( + type(value), + ) + ) + + if len(value) != len(self.encoders): + raise ValueOutOfBounds( + "Expected value with length {0}. Provided value has {1} " + "elements".format(len(self.encoders), len(value)) + ) + + for item, encoder in zip(value, self.encoders): + encoder.validate_value(item) + + def encode(self, values): + self.validate_value(values) + + raw_head_chunks = [] + tail_chunks = [] + for value, encoder in zip(values, self.encoders): + if encoder.is_dynamic: + raw_head_chunks.append(None) + tail_chunks.append(encoder(value)) + else: + raw_head_chunks.append(encoder(value)) + tail_chunks.append(b'') + + head_length = sum( + 32 if item is None else len(item) + for item in raw_head_chunks + ) + tail_offsets = (0,) + tuple(accumulate(map(len, tail_chunks[:-1]))) + head_chunks = tuple( + encode_uint_256(head_length + offset) if chunk is None else chunk + for chunk, offset in zip(raw_head_chunks, tail_offsets) + ) + + encoded_value = b''.join(head_chunks + tuple(tail_chunks)) + + return encoded_value + + @parse_tuple_type_str + def from_type_str(cls, abi_type, registry): + encoders = tuple(registry.get_encoder(str(c)) for c in abi_type.components) + + return cls(encoders=encoders) + + +class FixedSizeEncoder(BaseEncoder): + value_bit_size = None + data_byte_size = None + encode_fn = None + type_check_fn = None + is_big_endian = None + + def validate(self): + super().validate() + + if self.value_bit_size is None: + raise ValueError("`value_bit_size` may not be none") + if self.data_byte_size is None: + raise ValueError("`data_byte_size` may not be none") + if self.encode_fn is None: + raise ValueError("`encode_fn` may not be none") + if self.is_big_endian is None: + raise ValueError("`is_big_endian` may not be none") + + if self.value_bit_size % 8 != 0: + raise ValueError( + "Invalid value bit size: {0}. Must be a multiple of 8".format( + self.value_bit_size, + ) + ) + + if self.value_bit_size > self.data_byte_size * 8: + raise ValueError("Value byte size exceeds data size") + + def validate_value(self, value): + raise NotImplementedError("Must be implemented by subclasses") + + def encode(self, value): + self.validate_value(value) + base_encoded_value = self.encode_fn(value) + + if self.is_big_endian: + padded_encoded_value = zpad(base_encoded_value, self.data_byte_size) + else: + padded_encoded_value = zpad_right(base_encoded_value, self.data_byte_size) + + return padded_encoded_value + + +class Fixed32ByteSizeEncoder(FixedSizeEncoder): + data_byte_size = 32 + + +class BooleanEncoder(Fixed32ByteSizeEncoder): + value_bit_size = 8 + is_big_endian = True + + @classmethod + def validate_value(cls, value): + if not is_boolean(value): + raise EncodingTypeError( + "Value of type {0} cannot be encoded by {1}".format( + type(value), + cls.__name__, + ) + ) + + @classmethod + def encode_fn(cls, value): + if value is True: + return b'\x01' + elif value is False: + return b'\x00' + else: + raise ValueError("Invariant") + + @parse_type_str('bool') + def from_type_str(cls, abi_type, registry): + return cls() + + +class NumberEncoder(Fixed32ByteSizeEncoder): + is_big_endian = True + bounds_fn = None + illegal_value_fn = None + type_check_fn = None + + def validate(self): + super().validate() + + if self.bounds_fn is None: + raise ValueError("`bounds_fn` cannot be null") + if self.type_check_fn is None: + raise ValueError("`type_check_fn` cannot be null") + + def validate_value(self, value): + cls = type(self) + if not self.type_check_fn(value): + raise EncodingTypeError( + "Value of type {0} cannot be encoded by {1}".format( + type(value), + cls.__name__, + ) + ) + + illegal_value = ( + self.illegal_value_fn is not None + and self.illegal_value_fn(value) + ) + if illegal_value: + raise IllegalValue( + 'Value {} cannot be encoded by {}'.format(repr(value), cls.__name__) + ) + + lower_bound, upper_bound = self.bounds_fn(self.value_bit_size) + if value < lower_bound or value > upper_bound: + raise ValueOutOfBounds( + "Value {0} cannot be encoded in {1} bits. Must be bounded " + "between [{2}, {3}]".format( + repr(value), + self.value_bit_size, + lower_bound, + upper_bound, + ) + ) + + +class UnsignedIntegerEncoder(NumberEncoder): + encode_fn = staticmethod(int_to_big_endian) + bounds_fn = staticmethod(compute_unsigned_integer_bounds) + type_check_fn = staticmethod(is_integer) + + @parse_type_str('uint') + def from_type_str(cls, abi_type, registry): + return cls(value_bit_size=abi_type.sub) + + +encode_uint_256 = UnsignedIntegerEncoder(value_bit_size=256, data_byte_size=32) + + +class SignedIntegerEncoder(NumberEncoder): + bounds_fn = staticmethod(compute_signed_integer_bounds) + type_check_fn = staticmethod(is_integer) + + def encode_fn(self, value): + return int_to_big_endian(value % (2 ** self.value_bit_size)) + + def encode(self, value): + self.validate_value(value) + base_encoded_value = self.encode_fn(value) + + if value >= 0: + padded_encoded_value = zpad(base_encoded_value, self.data_byte_size) + else: + padded_encoded_value = fpad(base_encoded_value, self.data_byte_size) + + return padded_encoded_value + + @parse_type_str('int') + def from_type_str(cls, abi_type, registry): + return cls(value_bit_size=abi_type.sub) + + +class BaseFixedEncoder(NumberEncoder): + frac_places = None + + @staticmethod + def type_check_fn(value): + return is_number(value) and not isinstance(value, float) + + @staticmethod + def illegal_value_fn(value): + if isinstance(value, decimal.Decimal): + return value.is_nan() or value.is_infinite() + + return False + + def validate_value(self, value): + super().validate_value(value) + + with decimal.localcontext(abi_decimal_context): + residue = value % (TEN ** -self.frac_places) + + if residue > 0: + raise IllegalValue( + '{} cannot encode value {}: ' + 'residue {} outside allowed fractional precision of {}'.format( + type(self).__name__, + repr(value), + repr(residue), + self.frac_places, + ) + ) + + def validate(self): + super().validate() + + if self.frac_places is None: + raise ValueError("must specify `frac_places`") + + if self.frac_places <= 0 or self.frac_places > 80: + raise ValueError("`frac_places` must be in range (0, 80]") + + +class UnsignedFixedEncoder(BaseFixedEncoder): + def bounds_fn(self, value_bit_size): + return compute_unsigned_fixed_bounds(self.value_bit_size, self.frac_places) + + def encode_fn(self, value): + with decimal.localcontext(abi_decimal_context): + scaled_value = value * TEN ** self.frac_places + integer_value = int(scaled_value) + + return int_to_big_endian(integer_value) + + @parse_type_str('ufixed') + def from_type_str(cls, abi_type, registry): + value_bit_size, frac_places = abi_type.sub + + return cls( + value_bit_size=value_bit_size, + frac_places=frac_places, + ) + + +class SignedFixedEncoder(BaseFixedEncoder): + def bounds_fn(self, value_bit_size): + return compute_signed_fixed_bounds(self.value_bit_size, self.frac_places) + + def encode_fn(self, value): + with decimal.localcontext(abi_decimal_context): + scaled_value = value * TEN ** self.frac_places + integer_value = int(scaled_value) + + unsigned_integer_value = integer_value % (2 ** self.value_bit_size) + + return int_to_big_endian(unsigned_integer_value) + + def encode(self, value): + self.validate_value(value) + base_encoded_value = self.encode_fn(value) + + if value >= 0: + padded_encoded_value = zpad(base_encoded_value, self.data_byte_size) + else: + padded_encoded_value = fpad(base_encoded_value, self.data_byte_size) + + return padded_encoded_value + + @parse_type_str('fixed') + def from_type_str(cls, abi_type, registry): + value_bit_size, frac_places = abi_type.sub + + return cls( + value_bit_size=value_bit_size, + frac_places=frac_places, + ) + + +class BaseRealEncoder(NumberEncoder): + low_bit_size = None + high_bit_size = None + type_check_fn = staticmethod(is_number) + + def validate(self): + super().validate() + + if self.high_bit_size is None: + raise ValueError("`high_bit_size` cannot be null") + if self.low_bit_size is None: + raise ValueError("`low_bit_size` cannot be null") + if self.low_bit_size + self.high_bit_size != self.value_bit_size: + raise ValueError("high and low bitsizes must sum to the value_bit_size") + + +class UnsignedRealEncoder(BaseRealEncoder): + def bounds_fn(self, value_bit_size): + return compute_unsigned_real_bounds(self.high_bit_size, self.low_bit_size) + + def encode_fn(self, value): + scaled_value = value * 2 ** self.low_bit_size + integer_value = int(scaled_value) + return int_to_big_endian(integer_value) + + @parse_type_str('ureal') + def from_type_str(cls, abi_type, registry): + high_bit_size, low_bit_size = abi_type.sub + + return cls( + value_bit_size=high_bit_size + low_bit_size, + high_bit_size=high_bit_size, + low_bit_size=low_bit_size, + ) + + +class SignedRealEncoder(BaseRealEncoder): + def bounds_fn(self, value_bit_size): + return compute_signed_real_bounds(self.high_bit_size, self.low_bit_size) + + def encode_fn(self, value): + scaled_value = value * 2 ** self.low_bit_size + integer_value = int(scaled_value) + unsigned_integer_value = integer_value % (2 ** (self.high_bit_size + self.low_bit_size)) + + return int_to_big_endian(unsigned_integer_value) + + def encode(self, value): + self.validate_value(value) + base_encoded_value = self.encode_fn(value) + + if value >= 0: + padded_encoded_value = zpad(base_encoded_value, self.data_byte_size) + else: + padded_encoded_value = fpad(base_encoded_value, self.data_byte_size) + + return padded_encoded_value + + @parse_type_str('real') + def from_type_str(cls, abi_type, registry): + high_bit_size, low_bit_size = abi_type.sub + + return cls( + value_bit_size=high_bit_size + low_bit_size, + high_bit_size=high_bit_size, + low_bit_size=low_bit_size, + ) + + +class AddressEncoder(Fixed32ByteSizeEncoder): + value_bit_size = 20 * 8 + encode_fn = staticmethod(to_canonical_address) + is_big_endian = True + + @classmethod + def validate_value(cls, value): + if not is_address(value): + raise EncodingTypeError( + "Value of type {0} cannot be encoded by {1}".format( + type(value), + cls.__name__, + ) + ) + + def validate(self): + super().validate() + + if self.value_bit_size != 20 * 8: + raise ValueError('Addresses must be 160 bits in length') + + @parse_type_str('address') + def from_type_str(cls, abi_type, registry): + return cls() + + +class BytesEncoder(Fixed32ByteSizeEncoder): + is_big_endian = False + + def validate_value(self, value): + if not is_bytes(value): + raise EncodingTypeError( + "Value of type {0} cannot be encoded by {1}".format( + type(value), + type(self).__name__, + ) + ) + if len(value) > self.value_bit_size // 8: + raise ValueOutOfBounds( + "String {0} exceeds total byte size for bytes{1} encoding".format( + value, + self.value_bit_size // 8, + ) + ) + + @staticmethod + def encode_fn(value): + return value + + @parse_type_str('bytes') + def from_type_str(cls, abi_type, registry): + return cls(value_bit_size=abi_type.sub * 8) + + +class ByteStringEncoder(BaseEncoder): + is_dynamic = True + + @classmethod + def validate_value(cls, value): + if not is_bytes(value): + raise EncodingTypeError( + "Value of type {} cannot be encoded by {}".format( + type(value), + cls.__name__, + ) + ) + + @classmethod + def encode(cls, value): + cls.validate_value(value) + + if not value: + padded_value = b'\x00' * 32 + else: + padded_value = zpad_right(value, ceil32(len(value))) + + encoded_size = encode_uint_256(len(value)) + encoded_value = encoded_size + padded_value + + return encoded_value + + @parse_type_str('bytes') + def from_type_str(cls, abi_type, registry): + return cls() + + +class TextStringEncoder(BaseEncoder): + is_dynamic = True + + @classmethod + def validate_value(cls, value): + if not is_text(value): + raise EncodingTypeError( + "Value of type {} cannot be encoded by {}".format( + type(value), + cls.__name__, + ) + ) + + @classmethod + def encode(cls, value): + cls.validate_value(value) + + value_as_bytes = codecs.encode(value, 'utf8') + + if not value_as_bytes: + padded_value = b'\x00' * 32 + else: + padded_value = zpad_right(value_as_bytes, ceil32(len(value_as_bytes))) + + encoded_size = encode_uint_256(len(value_as_bytes)) + encoded_value = encoded_size + padded_value + + return encoded_value + + @parse_type_str('string') + def from_type_str(cls, abi_type, registry): + return cls() + + +class BaseArrayEncoder(BaseEncoder): + item_encoder = None + + def validate(self): + super().validate() + + if self.item_encoder is None: + raise ValueError("`item_encoder` may not be none") + + def validate_value(self, value): + if not is_list_like(value): + raise EncodingTypeError( + "Cannot encode value of type {0} using array encoder. Must be " + "a list-like object such as an array or tuple".format( + type(value), + ) + ) + + for item in value: + self.item_encoder.validate_value(item) + + def encode_elements(self, value): + self.validate_value(value) + + item_encoder = self.item_encoder + tail_chunks = tuple(item_encoder(i) for i in value) + + items_are_dynamic = getattr(item_encoder, 'is_dynamic', False) + if not items_are_dynamic: + return b''.join(tail_chunks) + + head_length = 32 * len(value) + tail_offsets = (0,) + tuple(accumulate(map(len, tail_chunks[:-1]))) + head_chunks = tuple( + encode_uint_256(head_length + offset) + for offset in tail_offsets + ) + return b''.join(head_chunks + tail_chunks) + + @parse_type_str(with_arrlist=True) + def from_type_str(cls, abi_type, registry): + item_encoder = registry.get_encoder(str(abi_type.item_type)) + + array_spec = abi_type.arrlist[-1] + if len(array_spec) == 1: + # If array dimension is fixed + return SizedArrayEncoder( + array_size=array_spec[0], + item_encoder=item_encoder, + ) + else: + # If array dimension is dynamic + return DynamicArrayEncoder(item_encoder=item_encoder) + + +class SizedArrayEncoder(BaseArrayEncoder): + array_size = None + + def __init__(self, **kwargs): + super().__init__(**kwargs) + + self.is_dynamic = self.item_encoder.is_dynamic + + def validate(self): + super().validate() + + if self.array_size is None: + raise ValueError("`array_size` may not be none") + + def validate_value(self, value): + super().validate_value(value) + + if len(value) != self.array_size: + raise ValueOutOfBounds( + "Expected value with length {0}. Provided value has {1} " + "elements".format(self.array_size, len(value)) + ) + + def encode(self, value): + encoded_elements = self.encode_elements(value) + + return encoded_elements + + +class DynamicArrayEncoder(BaseArrayEncoder): + is_dynamic = True + + def encode(self, value): + encoded_size = encode_uint_256(len(value)) + encoded_elements = self.encode_elements(value) + encoded_value = encoded_size + encoded_elements + + return encoded_value diff --git a/client_sdk_python/packages/eth_abi/exceptions.py b/client_sdk_python/packages/eth_abi/exceptions.py new file mode 100644 index 0000000..bd153ef --- /dev/null +++ b/client_sdk_python/packages/eth_abi/exceptions.py @@ -0,0 +1,58 @@ +import parsimonious + + +class EncodingError(Exception): + pass + + +class EncodingTypeError(EncodingError): + """ + Raised when trying to encode a value which is of the wrong type for the + desired encoding type. + """ + pass + + +class IllegalValue(EncodingError): + """ + Raised when trying to encode a value which is not considered legal for a + data type. + + Examples: + fixed128x19_encoder(Decimal('NaN')) # cannot encode NaN + ufixed8x1_encoder(Decimal('25.6')) # out of bounds + """ + pass + + +class ValueOutOfBounds(IllegalValue): + """ + Raised when trying to encode a value which is out bounds for the desired + type. + """ + pass + + +class DecodingError(Exception): + pass + + +class InsufficientDataBytes(DecodingError): + pass + + +class NonEmptyPaddingBytes(DecodingError): + pass + + +class ParseError(parsimonious.ParseError): + def __str__(self): + return "Parse error at '{}' (column {}) in type string '{}'".format( + self.text[self.pos:self.pos + 5], + self.column(), + self.text, + ) + + +class ABITypeError(ValueError): + pass diff --git a/client_sdk_python/packages/eth_abi/grammar.py b/client_sdk_python/packages/eth_abi/grammar.py new file mode 100644 index 0000000..019064c --- /dev/null +++ b/client_sdk_python/packages/eth_abi/grammar.py @@ -0,0 +1,384 @@ +import functools +import re + +from parsimonious import expressions +import parsimonious + +from client_sdk_python.packages.eth_abi.exceptions import ( + ABITypeError, + ParseError, +) + + +grammar = parsimonious.Grammar(r""" +type = tuple_type / basic_type + +tuple_type = components arrlist? +components = non_zero_tuple / zero_tuple + +non_zero_tuple = "(" type next_type* ")" +next_type = "," type + +zero_tuple = "()" + +basic_type = base sub? arrlist? + +base = alphas + +sub = two_size / digits +two_size = (digits "x" digits) + +arrlist = (const_arr / dynam_arr)+ +const_arr = "[" digits "]" +dynam_arr = "[]" + +alphas = ~"[a-z]+" +digits = ~"[1-9][0-9]*" +""") + + +class NodeVisitor(parsimonious.NodeVisitor): + """ + Parsimonious node visitor which performs both parsing of type strings and + post-processing of parse trees. Parsing operations are cached. + """ + grammar = grammar + + def visit_non_zero_tuple(self, node, visited_children): + # Ignore left and right parens + _, first, rest, _ = visited_children + + return (first,) + rest + + def visit_tuple_type(self, node, visited_children): + components, arrlist = visited_children + return TupleType(components, arrlist=arrlist, node=node) + + def visit_next_type(self, node, visited_children): + # Ignore comma + _, abi_type = visited_children + + return abi_type + + def visit_zero_tuple(self, node, visited_children): + return tuple() + + def visit_basic_type(self, node, visited_children): + base, sub, arrlist = visited_children + + return BasicType(base, sub, arrlist, node=node) + + def visit_two_size(self, node, visited_children): + # Ignore "x" + first, _, second = visited_children + + return first, second + + def visit_const_arr(self, node, visited_children): + # Ignore left and right brackets + _, int_value, _ = visited_children + + return (int_value,) + + def visit_dynam_arr(self, node, visited_children): + return tuple() + + def visit_alphas(self, node, visited_children): + return node.text + + def visit_digits(self, node, visited_children): + return int(node.text) + + def generic_visit(self, node, visited_children): + if isinstance(node.expr, expressions.OneOf): + # Unwrap value chosen from alternatives + return visited_children[0] + + if isinstance(node.expr, expressions.Optional): + # Unwrap optional value or return `None` + if len(visited_children) != 0: + return visited_children[0] + + return None + + return tuple(visited_children) + + @functools.lru_cache(maxsize=None) + def parse(self, type_str): + """ + Caches and returns results of parsing operations. Wraps any raised + parsing errors in a custom error class. + """ + if not isinstance(type_str, str): + raise TypeError('Can only parse string values: got {}'.format(type(type_str))) + + try: + return super().parse(type_str) + except parsimonious.ParseError as e: + raise ParseError(e.text, e.pos, e.expr) + + +visitor = NodeVisitor() + + +class ABIType: + """ + Base class for classes which represent the results of parsing operations on + abi type strings after post-processing. + """ + __slots__ = ('arrlist', 'node') + + def __init__(self, arrlist=None, node=None): + # Any type might have a list of array dimensions + self.arrlist = arrlist + + # The parsimonious `Node` instance associated with this parsed type may + # be optionally included. If a type must be validated during a parsing + # operation, the `Node` instance is required since the `invalidate` + # method expects it. + self.node = node + + def __repr__(self): # pragma: no cover + return '<{} {}>'.format(type(self).__qualname__, repr(str(self))) + + def __eq__(self, other): + """ + Two ABI types are equal if their canonical string representations are + equal. + """ + return ( + type(self) is type(other) and + str(self) == str(other) + ) + + def __str__(self): # pragma: no cover + """ + An ABI type must have a canonical string representation. + """ + raise NotImplementedError('Must implement `__str__`') + + def validate(self): # pragma: no cover + """ + An ABI type must be able to validate itself against the solidity ABI + spec: + https://solidity.readthedocs.io/en/develop/abi-spec.html + """ + raise NotImplementedError('Must implement `validate`') + + def invalidate(self, error_msg): + """ + Invalidates an ABI type with the given error message. Expects that a + parsimonious node was provided from the original parsing operation that + yielded this type. + """ + node = self.node + + raise ABITypeError( + "For '{comp_str}' type at column {col} " + "in '{type_str}': {error_msg}".format( + comp_str=node.text, + col=node.start + 1, + type_str=node.full_text, + error_msg=error_msg, + ), + ) + + +class TupleType(ABIType): + """ + Represents the result of parsing a type string which contains a tuple abi + type. + + e.g. "(int,bool)" + """ + __slots__ = ('components',) + + def __init__(self, components, arrlist=None, *, node=None): + super().__init__(arrlist, node) + + self.components = components + + def __str__(self): + arrlist = self.arrlist + if isinstance(arrlist, tuple): + arrlist = ''.join(repr(list(a)) for a in arrlist) + else: + arrlist = '' + return '({}){}'.format(','.join(str(c) for c in self.components), arrlist) + + @property + def item_type(self): + """ + If this type is an array type, returns the type of the array's items. + """ + if self.arrlist is None: + raise ValueError( + "Cannot determine item type for non-array type '{}'".format(self) + ) + + return type(self)( + self.components, + self.arrlist[:-1] or None, + node=self.node, + ) + + def validate(self): + # A tuple type is valid if all of its components are valid i.e. if none + # of its components contain an invalid type such as "uint7" + for c in self.components: + c.validate() + + +class BasicType(ABIType): + """ + Represents the result of parsing a type string which contains a basic abi + type. + + e.g. "uint", "address", "ufixed128x19[][2]" + """ + __slots__ = ('base', 'sub') + + def __init__(self, base, sub=None, arrlist=None, *, node=None): + super().__init__(arrlist, node) + + self.base = base + self.sub = sub + + def __str__(self): + sub, arrlist = self.sub, self.arrlist + + if isinstance(sub, int): + sub = str(sub) + elif isinstance(sub, tuple): + sub = 'x'.join(str(s) for s in sub) + else: + sub = '' + + if isinstance(arrlist, tuple): + arrlist = ''.join(repr(list(a)) for a in arrlist) + else: + arrlist = '' + + return self.base + sub + arrlist + + @property + def item_type(self): + """ + If this type is an array type, returns the type of the array's items. + """ + if self.arrlist is None: + raise ValueError( + "Cannot determine item type for non-array type '{}'".format(self) + ) + + return type(self)( + self.base, + self.sub, + self.arrlist[:-1] or None, + node=self.node, + ) + + def validate(self): + """ + A basic type is valid if it appears to be one of the default types + described in the solidity ABI spec and its components don't violate any + of the assumptions set forth in that spec -or- if it does not appear to + be a default type. + + Details found here: + https://solidity.readthedocs.io/en/develop/abi-spec.html + """ + base, sub = self.base, self.sub + + # Check validity of string type + if base == 'string': + if sub is not None: + self.invalidate('string type cannot have suffix') + + # Check validity of bytes type + elif base == 'bytes': + if not (sub is None or isinstance(sub, int)): + self.invalidate('bytes type must have either no suffix or a numerical suffix') + + if isinstance(sub, int) and sub > 32: + self.invalidate('maximum 32 bytes for fixed-length bytes') + + # Check validity of integer type + elif base in ('int', 'uint'): + if not isinstance(sub, int): + self.invalidate('integer type must have numerical suffix') + + if sub < 8 or 256 < sub: + self.invalidate('integer size out of bounds (max 256 bits)') + + if sub % 8 != 0: + self.invalidate('integer size must be multiple of 8') + + # Check validity of fixed type + elif base in ('fixed', 'ufixed'): + if not isinstance(sub, tuple): + self.invalidate( + 'fixed type must have suffix of form x, e.g. 128x19', + ) + + bits, minus_e = sub + + if bits < 8 or 256 < bits: + self.invalidate('fixed size out of bounds (max 256 bits)') + + if bits % 8 != 0: + self.invalidate('fixed size must be multiple of 8') + + if minus_e < 1 or 80 < minus_e: + self.invalidate( + 'fixed exponent size out of bounds, {} must be in 1-80'.format( + minus_e, + ), + ) + + # Check validity of real type + elif base in ('real', 'ureal'): + if not isinstance(sub, tuple): + self.invalidate('real type must have suffix of form x, e.g. 128x128') + + high, low = sub + + if (high + low) < 8 or 256 < (high + low): + self.invalidate('real size out of bounds (max 256 bits)') + + if high % 8 != 0 or low % 8 != 0: + self.invalidate('real high/low sizes must be multiples of 8') + + # Check validity of hash type + elif base == 'hash': + if not isinstance(sub, int): + self.invalidate('hash type must have numerical suffix') + + # Check validity of address type + elif base == 'address': + if sub is not None: + self.invalidate('address cannot have suffix') + + +TYPE_ALIASES = { + 'int': 'int256', + 'uint': 'uint256', + 'fixed': 'fixed128x18', + 'ufixed': 'ufixed128x18', + 'function': 'bytes24', +} + +TYPE_ALIAS_RE = re.compile(r'\b({})\b'.format( + '|'.join(re.escape(a) for a in TYPE_ALIASES.keys()) +)) + + +def normalize(type_str): + # Replace aliases with substitutions + return TYPE_ALIAS_RE.sub( + lambda match: TYPE_ALIASES[match.group(0)], + type_str, + ) + + +parse = visitor.parse diff --git a/client_sdk_python/packages/eth_abi/py.typed b/client_sdk_python/packages/eth_abi/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/client_sdk_python/packages/eth_abi/registry.py b/client_sdk_python/packages/eth_abi/registry.py new file mode 100644 index 0000000..028edec --- /dev/null +++ b/client_sdk_python/packages/eth_abi/registry.py @@ -0,0 +1,406 @@ +import functools + +from . import ( + decoding, + encoding, + exceptions, + grammar, +) + +from .base import BaseCoder + + +class PredicateMapping: + """ + Acts as a mapping from predicate functions to values. Values are retrieved + when their corresponding predicate matches a given input. Predicates can + also be labeled to facilitate removal from the mapping. + """ + def __init__(self, name): + self._name = name + self._values = {} + self._labeled_predicates = {} + + def add(self, predicate, value, label=None): + if predicate in self._values: + raise ValueError('Matcher {} already exists in {}'.format( + repr(predicate), + self._name, + )) + + if label is not None: + if label in self._labeled_predicates: + raise ValueError( + "Matcher {} with label '{}' already exists in {}".format( + repr(predicate), + label, + self._name, + ), + ) + + self._labeled_predicates[label] = predicate + + self._values[predicate] = value + + def find(self, type_str): + results = tuple( + (predicate, value) for predicate, value in self._values.items() + if predicate(type_str) + ) + + if len(results) == 0: + raise ValueError("No matching entries for '{}' in {}".format( + type_str, + self._name, + )) + + predicates, values = tuple(zip(*results)) + + if len(results) > 1: + raise ValueError("Multiple matching entries for '{}' in {}: {}".format( + type_str, + self._name, + ', '.join(map(repr, predicates)), + )) + + return values[0] + + def remove_by_equality(self, predicate): + # Delete the predicate mapping to the previously stored value + try: + del self._values[predicate] + except KeyError: + raise KeyError('Matcher {} not found in {}'.format( + repr(predicate), + self._name, + )) + + # Delete any label which refers to this predicate + try: + label = self._label_for_predicate(predicate) + except ValueError: + pass + else: + del self._labeled_predicates[label] + + def _label_for_predicate(self, predicate): + # Both keys and values in `_labeled_predicates` are unique since the + # `add` method enforces this + for key, value in self._labeled_predicates.items(): + if value is predicate: + return key + + raise ValueError('Matcher {} not referred to by any label in {}'.format( + repr(predicate), + self._name, + )) + + def remove_by_label(self, label): + try: + predicate = self._labeled_predicates[label] + except KeyError: + raise KeyError("Label '{}' not found in {}".format(label, self._name)) + + del self._labeled_predicates[label] + del self._values[predicate] + + def remove(self, predicate_or_label): + if callable(predicate_or_label): + self.remove_by_equality(predicate_or_label) + elif isinstance(predicate_or_label, str): + self.remove_by_label(predicate_or_label) + else: + raise TypeError('Key to be removed must be callable or string: got {}'.format( + type(predicate_or_label), + )) + + +class Predicate: + """ + A class which represents a predicate function to be used for type matching + in ABIRegistry. + """ + __slots__ = tuple() + + def __call__(self, *args, **kwargs): # pragma: no cover + raise NotImplementedError('Must implement `__call__`') + + def __str__(self): # pragma: no cover + raise NotImplementedError('Must implement `__str__`') + + def __repr__(self): + return '<{} {}>'.format(type(self).__name__, self) + + def __iter__(self): + for attr in self.__slots__: + yield getattr(self, attr) + + def __hash__(self): + return hash(tuple(self)) + + def __eq__(self, other): + return ( + type(self) is type(other) and + tuple(self) == tuple(other) + ) + + +class Equals(Predicate): + """ + A predicate which matches any input equal to `value`. + """ + __slots__ = ('value',) + + def __init__(self, value): + self.value = value + + def __call__(self, other): + return self.value == other + + def __str__(self): + return '(== {})'.format(repr(self.value)) + + +class BaseEquals(Predicate): + """ + A predicate which matches a basic type string with a base component equal to + `value` and no array component. If `with_sub` is `True`, the type string + must have a sub component to match. If `with_sub` is `False`, the type + string must *not* have a sub component to match. If `with_sub` is None, the + type string's sub component is ignored. + """ + __slots__ = ('base', 'with_sub') + + def __init__(self, base, *, with_sub=None): + self.base = base + self.with_sub = with_sub + + def __call__(self, type_str): + try: + abi_type = grammar.parse(type_str) + except exceptions.ParseError: + return False + + if isinstance(abi_type, grammar.BasicType): + if abi_type.arrlist is not None: + return False + + if self.with_sub is not None: + if self.with_sub and abi_type.sub is None: + return False + if not self.with_sub and abi_type.sub is not None: + return False + + return abi_type.base == self.base + + # We'd reach this point if `type_str` did not contain a basic type + # e.g. if it contained a tuple type + return False + + def __str__(self): + return '(base == {}{})'.format( + repr(self.base), + '' if self.with_sub is None else ( + ' and sub is not None' if self.with_sub else ' and sub is None' + ), + ) + + +def has_arrlist(type_str): + """ + A predicate which matches a type string with an array dimension list. + """ + try: + abi_type = grammar.parse(type_str) + except exceptions.ParseError: + return False + + return abi_type.arrlist is not None + + +def is_base_tuple(type_str): + """ + A predicate which matches a tuple type with no array dimension list. + """ + try: + abi_type = grammar.parse(type_str) + except exceptions.ParseError: + return False + + return isinstance(abi_type, grammar.TupleType) and abi_type.arrlist is None + + +def _clear_encoder_cache(old_method): + def new_method(self, *args, **kwargs): + self.get_encoder.cache_clear() + return old_method(self, *args, **kwargs) + + return new_method + + +def _clear_decoder_cache(old_method): + def new_method(self, *args, **kwargs): + self.get_decoder.cache_clear() + return old_method(self, *args, **kwargs) + + return new_method + + +class ABIRegistry: + def __init__(self): + self._encoders = PredicateMapping('encoder registry') + self._decoders = PredicateMapping('decoder registry') + + @staticmethod + def _register_coder(mapping, lookup, coder, label=None): + if callable(lookup): + mapping.add(lookup, coder, label) + return + + if isinstance(lookup, str): + mapping.add(Equals(lookup), coder, lookup) + return + + raise TypeError( + 'Lookup must be a callable or a value of type `str`: got {}'.format( + repr(lookup), + ) + ) + + @staticmethod + def _unregister_coder(mapping, lookup_or_label): + if callable(lookup_or_label): + mapping.remove_by_equality(lookup_or_label) + return + + if isinstance(lookup_or_label, str): + mapping.remove_by_label(lookup_or_label) + return + + raise TypeError( + 'Lookup/label must be a callable or a value of type `str`: got {}'.format( + repr(lookup_or_label), + ) + ) + + def _get_coder(self, mapping, type_str): + try: + coder = mapping.find(type_str) + except ValueError as e: + if 'No matching' in e.args[0]: + # If no matches found, attempt to parse in case lack of matches + # was due to unparsability + grammar.parse(type_str) + + raise + + if isinstance(coder, type) and issubclass(coder, BaseCoder): + return coder.from_type_str(type_str, self) + + return coder + + @_clear_encoder_cache + def register_encoder(self, lookup, encoder, label=None): + self._register_coder(self._encoders, lookup, encoder, label=label) + + @_clear_encoder_cache + def unregister_encoder(self, lookup_or_label): + self._unregister_coder(self._encoders, lookup_or_label) + + @_clear_decoder_cache + def register_decoder(self, lookup, decoder, label=None): + self._register_coder(self._decoders, lookup, decoder, label=label) + + @_clear_decoder_cache + def unregister_decoder(self, lookup_or_label): + self._unregister_coder(self._decoders, lookup_or_label) + + def register(self, lookup, encoder, decoder, label=None): + self.register_encoder(lookup, encoder, label=label) + self.register_decoder(lookup, decoder, label=label) + + def unregister(self, lookup_or_label): + self.unregister_encoder(lookup_or_label) + self.unregister_decoder(lookup_or_label) + + @functools.lru_cache(maxsize=None) + def get_encoder(self, type_str): + return self._get_coder(self._encoders, type_str) + + @functools.lru_cache(maxsize=None) + def get_decoder(self, type_str): + return self._get_coder(self._decoders, type_str) + + +registry = ABIRegistry() + +registry.register( + BaseEquals('uint'), + encoding.UnsignedIntegerEncoder, decoding.UnsignedIntegerDecoder, + label='uint', +) +registry.register( + BaseEquals('int'), + encoding.SignedIntegerEncoder, decoding.SignedIntegerDecoder, + label='int', +) +registry.register( + BaseEquals('address'), + encoding.AddressEncoder, decoding.AddressDecoder, + label='address', +) +registry.register( + BaseEquals('bool'), + encoding.BooleanEncoder, decoding.BooleanDecoder, + label='bool', +) +registry.register( + BaseEquals('ufixed'), + encoding.UnsignedFixedEncoder, decoding.UnsignedFixedDecoder, + label='ufixed', +) +registry.register( + BaseEquals('fixed'), + encoding.SignedFixedEncoder, decoding.SignedFixedDecoder, + label='fixed', +) +registry.register( + BaseEquals('ureal'), + encoding.UnsignedRealEncoder, decoding.UnsignedRealDecoder, + label='ureal', +) +registry.register( + BaseEquals('real'), + encoding.SignedRealEncoder, decoding.SignedRealDecoder, + label='real', +) +registry.register( + BaseEquals('bytes', with_sub=True), + encoding.BytesEncoder, decoding.BytesDecoder, + label='bytes', +) +registry.register( + BaseEquals('bytes', with_sub=False), + encoding.ByteStringEncoder, decoding.ByteStringDecoder, + label='bytes', +) +registry.register( + BaseEquals('function'), + encoding.BytesEncoder, decoding.BytesDecoder, + label='function', +) +registry.register( + BaseEquals('string'), + encoding.TextStringEncoder, decoding.StringDecoder, + label='string', +) +registry.register( + has_arrlist, + encoding.BaseArrayEncoder, decoding.BaseArrayDecoder, + label='has_arrlist', +) +registry.register( + is_base_tuple, + encoding.TupleEncoder, decoding.TupleDecoder, + label='is_base_tuple', +) diff --git a/client_sdk_python/packages/eth_abi/utils/__init__.py b/client_sdk_python/packages/eth_abi/utils/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/client_sdk_python/packages/eth_abi/utils/numeric.py b/client_sdk_python/packages/eth_abi/utils/numeric.py new file mode 100644 index 0000000..bf5e27b --- /dev/null +++ b/client_sdk_python/packages/eth_abi/utils/numeric.py @@ -0,0 +1,77 @@ +import math +import decimal + + +abi_decimal_context = decimal.Context(prec=999) + +ZERO = decimal.Decimal(0) +TEN = decimal.Decimal(10) + + +def ceil32(x): + return x if x % 32 == 0 else x + 32 - (x % 32) + + +def compute_unsigned_integer_bounds(num_bits): + return ( + 0, + 2 ** num_bits - 1, + ) + + +def compute_signed_integer_bounds(num_bits): + return ( + -1 * 2 ** (num_bits - 1), + 2 ** (num_bits - 1) - 1, + ) + + +def compute_unsigned_fixed_bounds(num_bits, frac_places): + int_upper = compute_unsigned_integer_bounds(num_bits)[1] + + with decimal.localcontext(abi_decimal_context): + upper = decimal.Decimal(int_upper) * TEN ** -frac_places + + return ZERO, upper + + +def compute_signed_fixed_bounds(num_bits, frac_places): + int_lower, int_upper = compute_signed_integer_bounds(num_bits) + + with decimal.localcontext(abi_decimal_context): + exp = TEN ** -frac_places + lower = decimal.Decimal(int_lower) * exp + upper = decimal.Decimal(int_upper) * exp + + return lower, upper + + +def compute_unsigned_real_bounds(num_high_bits, num_low_bits): + integer_lower_bound, integer_upper_bount = compute_unsigned_integer_bounds( + num_high_bits, + ) + return ( + integer_lower_bound * 1.0 / 2 ** num_low_bits, + integer_upper_bount * 1.0 / 2 ** num_low_bits, + ) + + +def compute_signed_real_bounds(num_high_bits, num_low_bits): + integer_lower_bound, integer_upper_bount = compute_signed_integer_bounds( + num_high_bits, + ) + return ( + integer_lower_bound * 1.0 / 2 ** num_low_bits, + integer_upper_bount * 1.0 / 2 ** num_low_bits, + ) + + +def quantize_value(value, decimal_bit_size): + num_decimals = int(math.ceil(math.log10(2 ** decimal_bit_size))) + with decimal.localcontext(abi_decimal_context): + if num_decimals == 0: + quantize_value = decimal.Decimal('1') + else: + quantize_value = decimal.Decimal('1.{0}'.format(''.zfill(num_decimals))) + decimal_value = decimal.Decimal(value) + return decimal_value.quantize(quantize_value) diff --git a/client_sdk_python/packages/eth_abi/utils/padding.py b/client_sdk_python/packages/eth_abi/utils/padding.py new file mode 100644 index 0000000..6235a52 --- /dev/null +++ b/client_sdk_python/packages/eth_abi/utils/padding.py @@ -0,0 +1,27 @@ +from client_sdk_python.packages.eth_utils.toolz import ( + curry, +) + + +@curry +def zpad(value, length): + return value.rjust(length, b'\x00') + + +zpad32 = zpad(length=32) + + +@curry +def zpad_right(value, length): + return value.ljust(length, b'\x00') + + +zpad32_right = zpad_right(length=32) + + +@curry +def fpad(value, length): + return value.rjust(length, b'\xff') + + +fpad32 = fpad(length=32) diff --git a/client_sdk_python/packages/eth_abi/utils/parsing.py b/client_sdk_python/packages/eth_abi/utils/parsing.py new file mode 100644 index 0000000..dfeaac9 --- /dev/null +++ b/client_sdk_python/packages/eth_abi/utils/parsing.py @@ -0,0 +1,49 @@ +""" +This module provided for backwards compatibility. +""" +from client_sdk_python.packages.eth_abi.grammar import ( + TupleType, + normalize, + parse, +) + + +def process_type(type_str): + normalized_type_str = normalize(type_str) + abi_type = parse(normalized_type_str) + + type_str_repr = repr(type_str) + if type_str != normalized_type_str: + type_str_repr = '{} (normalized to {})'.format( + type_str_repr, + repr(normalized_type_str), + ) + + if isinstance(abi_type, TupleType): + raise ValueError( + "Cannot process type {}: tuple types not supported".format( + type_str_repr, + ) + ) + + abi_type.validate() + + sub = abi_type.sub + if isinstance(sub, tuple): + sub = 'x'.join(map(str, sub)) + elif isinstance(sub, int): + sub = str(sub) + else: + sub = '' + + arrlist = abi_type.arrlist + if isinstance(arrlist, tuple): + arrlist = list(map(list, arrlist)) + else: + arrlist = [] + + return abi_type.base, sub, arrlist + + +def collapse_type(base, sub, arrlist): + return base + sub + ''.join(map(repr, arrlist)) diff --git a/client_sdk_python/packages/eth_utils/__init__.py b/client_sdk_python/packages/eth_utils/__init__.py new file mode 100644 index 0000000..67b9c09 --- /dev/null +++ b/client_sdk_python/packages/eth_utils/__init__.py @@ -0,0 +1,112 @@ +import sys +import warnings + +import pkg_resources + +from .abi import ( # noqa: F401 + event_abi_to_log_topic, + event_signature_to_log_topic, + function_abi_to_4byte_selector, + function_signature_to_4byte_selector, + topic_decode, +) +from .address import ( # noqa: F401 + is_address, + is_binary_address, + is_canonical_address, + is_checksum_address, + is_checksum_formatted_address, + is_hex_address, + is_normalized_address, + is_same_address, + to_canonical_address, + to_checksum_address, + to_normalized_address, +) +from .applicators import ( # noqa: F401 + apply_formatter_at_index, + apply_formatter_if, + apply_formatter_to_array, + apply_formatters_to_dict, + apply_formatters_to_sequence, + apply_key_map, + apply_one_of_formatters, + combine_argument_formatters, +) +from .conversions import ( # noqa: F401 + hexstr_if_str, + text_if_str, + to_bytes, + to_hex, + to_int, + to_text, +) +from .crypto import keccak # noqa: F401 +from .currency import denoms, from_wei, to_wei # noqa: F401 +from .decorators import combomethod, replace_exceptions # noqa: F401 +from .encoding import big_endian_to_int, int_to_big_endian # noqa: F401 +from .exceptions import ValidationError # noqa: F401 +from .functional import ( # noqa: F401 + apply_to_return_value, + flatten_return, + reversed_return, + sort_return, + to_dict, + to_list, + to_ordered_dict, + to_set, + to_tuple, +) +from .hexadecimal import ( # noqa: F401 + add_0x_prefix, + decode_hex, + encode_hex, + is_0x_prefixed, + is_hex, + is_hexstr, + remove_0x_prefix, +) +from .humanize import ( # noqa: F401 + humanize_bytes, + humanize_hash, + humanize_integer_sequence, + humanize_ipfs_uri, + humanize_seconds, +) +from .logging import ( # noqa: F401 + DEBUG2_LEVEL_NUM, + ExtendedDebugLogger, + HasExtendedDebugLogger, + HasExtendedDebugLoggerMeta, + HasLogger, + HasLoggerMeta, + get_extended_debug_logger, + get_logger, + setup_DEBUG2_logging, +) +from .module_loading import import_string # noqa: F401 +from .numeric import clamp # noqa: F401 +from .types import ( # noqa: F401 + is_boolean, + is_bytes, + is_dict, + is_integer, + is_list, + is_list_like, + is_null, + is_number, + is_string, + is_text, + is_tuple, +) + +if sys.version_info.major < 3: + warnings.simplefilter("always", DeprecationWarning) + warnings.warn( + DeprecationWarning( + "The `eth-utils` library has dropped support for Python 2. Upgrade to Python 3." + ) + ) + warnings.resetwarnings() + + diff --git a/client_sdk_python/packages/eth_utils/__main__.py b/client_sdk_python/packages/eth_utils/__main__.py new file mode 100644 index 0000000..cb9bc0b --- /dev/null +++ b/client_sdk_python/packages/eth_utils/__main__.py @@ -0,0 +1,3 @@ +from .debug import get_environment_summary + +print(get_environment_summary()) diff --git a/client_sdk_python/packages/eth_utils/abi.py b/client_sdk_python/packages/eth_utils/abi.py new file mode 100644 index 0000000..a04007c --- /dev/null +++ b/client_sdk_python/packages/eth_utils/abi.py @@ -0,0 +1,101 @@ +from typing import Any, Dict + +from .crypto import keccak +from client_sdk_python.param_encode import ( + stringfnv, + rlp_encode, + rlp_decode, + hexstr2bytes, + tostring_hex, + stringtohex, +) +from eth_hash.auto import keccak as keccak_256 +from hexbytes import ( + HexBytes, +) +def collapse_if_tuple(abi: Dict[str, Any]) -> str: + """Converts a tuple from a dict to a parenthesized list of its types. + + >>> from eth_utils.abi import collapse_if_tuple + >>> collapse_if_tuple( + ... { + ... 'components': [ + ... {'name': 'anAddress', 'type': 'address'}, + ... {'name': 'anInt', 'type': 'uint256'}, + ... {'name': 'someBytes', 'type': 'bytes'}, + ... ], + ... 'type': 'tuple', + ... } + ... ) + '(address,uint256,bytes)' + """ + typ = abi["type"] + if not typ.startswith("tuple"): + return typ + + delimited = ",".join(collapse_if_tuple(c) for c in abi["components"]) + # Whatever comes after "tuple" is the array dims. The ABI spec states that + # this will have the form "", "[]", or "[k]". + array_dim = typ[5:] + collapsed = "({}){}".format(delimited, array_dim) + + return collapsed + + +def _abi_to_signature(abi: Dict[str, Any]) -> str: + function_signature = "{fn_name}({fn_input_types})".format( + fn_name=abi["name"], + fn_input_types=",".join( + [collapse_if_tuple(abi_input) for abi_input in abi.get("inputs", [])] + ), + ) + return function_signature + + +def function_signature_to_4byte_selector(event_signature: str) -> bytes: + return keccak(text=event_signature.replace(" ", ""))[:4] + + +def function_abi_to_4byte_selector(function_abi: Dict[str, Any]) -> bytes: + function_signature = _abi_to_signature(function_abi) + return function_signature_to_4byte_selector(function_signature) + + +def event_signature_to_log_topic(event_signature: str) -> bytes: + return keccak(text=event_signature.replace(" ", "")) + + +def event_abi_to_log_topic(event_abi: Dict[str, Any], vmtype=None) -> bytes: + if vmtype: + event_signature = event_abi['name'] + temp = stringtohex(bytes(event_signature, 'utf-8')) + if len(temp)<32: + data1=tostring_hex(temp) + data1=data1.rjust(64,'0') + data=HexBytes('0x'+data1) + elif len(temp)>32: + data1=[] + for i in range(len(temp)): + data1.append(int(event_signature[i], 16)) + data=keccak_256(bytes(data1)) + else: + data=tostring_hex(temp) + data=HexBytes('0x'+data) + return data + + # event_signature = rlp_encode(temp) + # event_signature1 = [] + # for i in range(len(event_signature)): + # event_signature1.append(int(event_signature[i], 16)) + # keccak_256(bytes(event_signature1)) + # return keccak_256(bytes(event_signature1)) + else: + event_signature = _abi_to_signature(event_abi) + return event_signature_to_log_topic(event_signature) +def topic_decode(data): + temp = [] + for i in data[0]: + if i: + temp.append(bytes.decode(HexBytes(i))) + data1 = ''.join(temp) + return [data1] \ No newline at end of file diff --git a/client_sdk_python/packages/eth_utils/address.py b/client_sdk_python/packages/eth_utils/address.py new file mode 100644 index 0000000..5a25d86 --- /dev/null +++ b/client_sdk_python/packages/eth_utils/address.py @@ -0,0 +1,153 @@ +from typing import Any, AnyStr + +from eth_typing import Address, AnyAddress, ChecksumAddress, HexAddress, HexStr +import codecs +from .conversions import hexstr_if_str, to_hex +from .crypto import keccak +from .hexadecimal import ( + add_0x_prefix, + decode_hex, + encode_hex, + is_hexstr, + remove_0x_prefix, +) +from .types import is_bytes, is_text + + +def is_hex_address(value: Any) -> bool: + """ + Checks if the given string of text type is an address in hexadecimal encoded form. + """ + if not is_hexstr(value): + return False + else: + unprefixed = remove_0x_prefix(value) + return len(unprefixed) == 40 + + +def is_binary_address(value: Any) -> bool: + """ + Checks if the given string is an address in raw bytes form. + """ + if not is_bytes(value): + return False + elif len(value) != 20: + return False + else: + return True + + +def is_address(value: Any) -> bool: + """ + Checks if the given string in a supported value + is an address in any of the known formats. + """ + if is_checksum_formatted_address(value): + return is_checksum_address(value) + elif is_hex_address(value): + return True + elif is_binary_address(value): + return True + else: + return False + + +def to_normalized_address(value: AnyStr) -> HexAddress: + """ + Converts an address to its normalized hexadecimal representation. + """ + try: + hex_address = hexstr_if_str(to_hex, value).lower() + except AttributeError: + raise TypeError( + "Value must be any string, instead got type {}".format(type(value)) + ) + if is_address(hex_address): #is_address(hex_address): + return HexAddress(hex_address) + else: + raise ValueError( + "Unknown format {}, attempted to normalize to {}".format(value, hex_address) + ) + + +def is_normalized_address(value: Any) -> bool: + """ + Returns whether the provided value is an address in its normalized form. + """ + if not is_address(value): + return False + else: + return value == to_normalized_address(value) + + +def to_canonical_address(address: AnyStr) -> Address: + """ + Given any supported representation of an address + returns its canonical form (20 byte long string). + """ + return Address(decode_hex(to_normalized_address(address))) + + +def is_canonical_address(address: Any) -> bool: + """ + Returns `True` if the `value` is an address in its canonical form. + """ + if not is_bytes(address) or len(address) != 20: + return False + return address == to_canonical_address(address) + + +def is_same_address(left: AnyAddress, right: AnyAddress) -> bool: + """ + Checks if both addresses are same or not. + """ + if not is_address(left) or not is_address(right): + raise ValueError("Both values must be valid addresses") + else: + return to_normalized_address(left) == to_normalized_address(right) + + +def to_checksum_address(value: AnyStr) -> ChecksumAddress: + """ + Makes a checksum address given a supported format. + """ + norm_address = to_normalized_address(value) + address_hash = encode_hex(keccak(text=remove_0x_prefix(HexStr(norm_address)))) + + checksum_address = add_0x_prefix( + HexStr( + "".join( + ( + norm_address[i].upper() + if int(address_hash[i], 16) > 7 + else norm_address[i] + ) + for i in range(2, 42) + ) + ) + ) + return ChecksumAddress(HexAddress(checksum_address)) + + +def is_checksum_address(value: Any) -> bool: + if not is_text(value): + return False + + if not is_hex_address(value): + return False + if isinstance(value, str): + if len(value) == 42: + return True + return value == to_checksum_address(value) + + +def is_checksum_formatted_address(value: Any) -> bool: + + if not is_hex_address(value): + return False + elif remove_0x_prefix(value) == remove_0x_prefix(value).lower(): + return False + elif remove_0x_prefix(value) == remove_0x_prefix(value).upper(): + return False + else: + return True diff --git a/client_sdk_python/packages/eth_utils/applicators.py b/client_sdk_python/packages/eth_utils/applicators.py new file mode 100644 index 0000000..bd72e9f --- /dev/null +++ b/client_sdk_python/packages/eth_utils/applicators.py @@ -0,0 +1,134 @@ +from typing import Any, Callable, Dict, Generator, List, Tuple +import warnings + +from .decorators import return_arg_type +from .functional import to_dict +from .toolz import compose, curry + +Formatters = Callable[[List[Any]], List[Any]] + + +@return_arg_type(2) +def apply_formatter_at_index( + formatter: Callable[..., Any], at_index: int, value: List[Any] +) -> Generator[List[Any], None, None]: + if at_index + 1 > len(value): + raise IndexError( + "Not enough values in iterable to apply formatter. Got: {0}. " + "Need: {1}".format(len(value), at_index + 1) + ) + for index, item in enumerate(value): + if index == at_index: + yield formatter(item) + else: + yield item + + +def combine_argument_formatters(*formatters: List[Callable[..., Any]]) -> Formatters: + warnings.warn( + DeprecationWarning( + "combine_argument_formatters(formatter1, formatter2)([item1, item2])" + "has been deprecated and will be removed in a subsequent major version " + "release of the eth-utils library. Update your calls to use " + "apply_formatters_to_sequence([formatter1, formatter2], [item1, item2]) " + "instead." + ) + ) + + _formatter_at_index = curry(apply_formatter_at_index) + return compose( + *( + _formatter_at_index(formatter, index) + for index, formatter in enumerate(formatters) + ) + ) + + +@return_arg_type(1) +def apply_formatters_to_sequence( + formatters: List[Any], sequence: List[Any] +) -> Generator[List[Any], None, None]: + if len(formatters) > len(sequence): + raise IndexError( + "Too many formatters for sequence: {} formatters for {!r}".format( + len(formatters), sequence + ) + ) + elif len(formatters) < len(sequence): + raise IndexError( + "Too few formatters for sequence: {} formatters for {!r}".format( + len(formatters), sequence + ) + ) + else: + for formatter, item in zip(formatters, sequence): + yield formatter(item) + + +def apply_formatter_if( + condition: Callable[..., bool], formatter: Callable[..., Any], value: Any +) -> Any: + if condition(value): + return formatter(value) + else: + return value + + +@to_dict +def apply_formatters_to_dict( + formatters: Dict[Any, Any], value: Dict[Any, Any] +) -> Generator[Tuple[Any, Any], None, None]: + for key, item in value.items(): + if key in formatters: + try: + yield key, formatters[key](item) + except (TypeError, ValueError) as exc: + raise type(exc)( + "Could not format value %r as field %r" % (item, key) + ) from exc + else: + yield key, item + + +@return_arg_type(1) +def apply_formatter_to_array( + formatter: Callable[..., Any], value: List[Any] +) -> Generator[List[Any], None, None]: + for item in value: + yield formatter(item) + + +def apply_one_of_formatters( + formatter_condition_pairs: Tuple[Tuple[Callable[..., Any], Callable[..., Any]]], + value: Any, +) -> Any: + for condition, formatter in formatter_condition_pairs: + if condition(value): + return formatter(value) + else: + raise ValueError( + "The provided value did not satisfy any of the formatter conditions" + ) + + +@to_dict +def apply_key_map( + key_mappings: Dict[Any, Any], value: Dict[Any, Any] +) -> Generator[Tuple[Any, Any], None, None]: + key_conflicts = ( + set(value.keys()) + .difference(key_mappings.keys()) + .intersection(v for k, v in key_mappings.items() if v in value) + ) + if key_conflicts: + raise KeyError( + "Could not apply key map due to conflicting key(s): {}".format( + key_conflicts + ) + ) + + for key, item in value.items(): + if key in key_mappings: + yield key_mappings[key], item + else: + yield key, item diff --git a/client_sdk_python/packages/eth_utils/conversions.py b/client_sdk_python/packages/eth_utils/conversions.py new file mode 100644 index 0000000..7b81ea1 --- /dev/null +++ b/client_sdk_python/packages/eth_utils/conversions.py @@ -0,0 +1,165 @@ +from typing import Callable, TypeVar, Union + +from eth_typing import HexStr, Primitives + +from .decorators import validate_conversion_arguments +from .encoding import big_endian_to_int, int_to_big_endian +from .hexadecimal import ( + add_0x_prefix, + decode_hex, + encode_hex, + is_hexstr, + remove_0x_prefix, +) +from .types import is_boolean, is_integer, is_string + +T = TypeVar("T") + + +@validate_conversion_arguments +def to_hex( + primitive: Primitives = None, hexstr: HexStr = None, text: str = None +) -> HexStr: + """ + Auto converts any supported value into its hex representation. + Trims leading zeros, as defined in: + https://github.com/ethereum/wiki/wiki/JSON-RPC#hex-value-encoding + """ + if hexstr is not None: + return add_0x_prefix(HexStr(hexstr.lower())) + + if text is not None: + return encode_hex(text.encode("utf-8")) + + if is_boolean(primitive): + return HexStr("0x1") if primitive else HexStr("0x0") + + if isinstance(primitive, (bytes, bytearray)): + return encode_hex(primitive) + elif is_string(primitive): + raise TypeError( + "Unsupported type: The primitive argument must be one of: bytes," + "bytearray, int or bool and not str" + ) + + if is_integer(primitive): + return HexStr(hex(primitive)) + + raise TypeError( + "Unsupported type: '{0}'. Must be one of: bool, str, bytes, bytearray" + "or int.".format(repr(type(primitive))) + ) + + +@validate_conversion_arguments +def to_int( + primitive: Primitives = None, hexstr: HexStr = None, text: str = None +) -> int: + """ + Converts value to its integer representation. + Values are converted this way: + + * primitive: + + * bytes, bytearrays: big-endian integer + * bool: True => 1, False => 0 + * hexstr: interpret hex as integer + * text: interpret as string of digits, like '12' => 12 + """ + if hexstr is not None: + return int(hexstr, 16) + elif text is not None: + return int(text) + elif isinstance(primitive, (bytes, bytearray)): + return big_endian_to_int(primitive) + elif isinstance(primitive, str): + raise TypeError("Pass in strings with keyword hexstr or text") + elif isinstance(primitive, (int, bool)): + return int(primitive) + else: + raise TypeError( + "Invalid type. Expected one of int/bool/str/bytes/bytearray. Got " + "{0}".format(type(primitive)) + ) + + +@validate_conversion_arguments +def to_bytes( + primitive: Primitives = None, hexstr: HexStr = None, text: str = None +) -> bytes: + if is_boolean(primitive): + return b"\x01" if primitive else b"\x00" + elif isinstance(primitive, bytearray): + return bytes(primitive) + elif isinstance(primitive, bytes): + return primitive + elif is_integer(primitive): + return to_bytes(hexstr=to_hex(primitive)) + elif hexstr is not None: + if len(hexstr) % 2: + # type check ignored here because casting an Optional arg to str is not possible + hexstr = "0x0" + remove_0x_prefix(hexstr) # type: ignore + return decode_hex(hexstr) + elif text is not None: + return text.encode("utf-8") + raise TypeError( + "expected a bool, int, byte or bytearray in first arg, or keyword of hexstr or text" + ) + + +@validate_conversion_arguments +def to_text( + primitive: Primitives = None, hexstr: HexStr = None, text: str = None +) -> str: + if hexstr is not None: + return to_bytes(hexstr=hexstr).decode("utf-8") + elif text is not None: + return text + elif isinstance(primitive, str): + return to_text(hexstr=primitive) + elif isinstance(primitive, (bytes, bytearray)): + return primitive.decode("utf-8") + elif is_integer(primitive): + byte_encoding = int_to_big_endian(primitive) + return to_text(byte_encoding) + raise TypeError("Expected an int, bytes, bytearray or hexstr.") + + +def text_if_str( + to_type: Callable[..., T], text_or_primitive: Union[bytes, int, str] +) -> T: + """ + Convert to a type, assuming that strings can be only unicode text (not a hexstr) + + :param to_type function: takes the arguments (primitive, hexstr=hexstr, text=text), + eg~ to_bytes, to_text, to_hex, to_int, etc + :param text_or_primitive bytes, str, int: value to convert + """ + if isinstance(text_or_primitive, str): + return to_type(text=text_or_primitive) + else: + return to_type(text_or_primitive) + + +def hexstr_if_str( + to_type: Callable[..., T], hexstr_or_primitive: Union[bytes, int, str] +) -> T: + """ + Convert to a type, assuming that strings can be only hexstr (not unicode text) + + :param to_type function: takes the arguments (primitive, hexstr=hexstr, text=text), + eg~ to_bytes, to_text, to_hex, to_int, etc + :param hexstr_or_primitive bytes, str, int: value to convert + """ + if isinstance(hexstr_or_primitive, str): + if remove_0x_prefix(HexStr(hexstr_or_primitive)) and not is_hexstr( + hexstr_or_primitive + ): + raise ValueError( + "when sending a str, it must be a hex string. Got: {0!r}".format( + hexstr_or_primitive + ) + ) + return to_type(hexstr=hexstr_or_primitive) + else: + return to_type(hexstr_or_primitive) diff --git a/client_sdk_python/packages/eth_utils/crypto.py b/client_sdk_python/packages/eth_utils/crypto.py new file mode 100644 index 0000000..b8308bc --- /dev/null +++ b/client_sdk_python/packages/eth_utils/crypto.py @@ -0,0 +1,11 @@ +from typing import Union + +from eth_hash.auto import keccak as keccak_256 + +from .conversions import to_bytes + + +def keccak( + primitive: Union[bytes, int, bool] = None, hexstr: str = None, text: str = None +) -> bytes: + return keccak_256(to_bytes(primitive, hexstr, text)) diff --git a/client_sdk_python/packages/eth_utils/currency.py b/client_sdk_python/packages/eth_utils/currency.py new file mode 100644 index 0000000..30bc312 --- /dev/null +++ b/client_sdk_python/packages/eth_utils/currency.py @@ -0,0 +1,102 @@ +import decimal +from decimal import localcontext +from typing import Union + +from .types import is_integer, is_string +from .units import units + + +class denoms: + wei = int(units["wei"]) + kwei = int(units["kwei"]) + babbage = int(units["babbage"]) + femtoether = int(units["femtoether"]) + mwei = int(units["mwei"]) + lovelace = int(units["lovelace"]) + picoether = int(units["picoether"]) + gwei = int(units["gwei"]) + shannon = int(units["shannon"]) + nanoether = int(units["nanoether"]) + nano = int(units["nano"]) + szabo = int(units["szabo"]) + microether = int(units["microether"]) + micro = int(units["micro"]) + finney = int(units["finney"]) + milliether = int(units["milliether"]) + milli = int(units["milli"]) + ether = int(units["ether"]) + kether = int(units["kether"]) + grand = int(units["grand"]) + mether = int(units["mether"]) + gether = int(units["gether"]) + tether = int(units["tether"]) + + +MIN_WEI = 0 +MAX_WEI = 2 ** 256 - 1 + + +def from_wei(number: int, unit: str) -> Union[int, decimal.Decimal]: + """ + Takes a number of wei and converts it to any other ether unit. + """ + if unit.lower() not in units: + raise ValueError( + "Unknown unit. Must be one of {0}".format("/".join(units.keys())) + ) + + if number == 0: + return 0 + + if number < MIN_WEI or number > MAX_WEI: + raise ValueError("value must be between 1 and 2**256 - 1") + + unit_value = units[unit.lower()] + + with localcontext() as ctx: + ctx.prec = 999 + d_number = decimal.Decimal(value=number, context=ctx) + result_value = d_number / unit_value + + return result_value + + +def to_wei(number: Union[int, float, str, decimal.Decimal], unit: str) -> int: + """ + Takes a number of a unit and converts it to wei. + """ + if unit.lower() not in units: + raise ValueError( + "Unknown unit. Must be one of {0}".format("/".join(units.keys())) + ) + + if is_integer(number) or is_string(number): + d_number = decimal.Decimal(value=number) + elif isinstance(number, float): + d_number = decimal.Decimal(value=str(number)) + elif isinstance(number, decimal.Decimal): + d_number = number + else: + raise TypeError("Unsupported type. Must be one of integer, float, or string") + + s_number = str(number) + unit_value = units[unit.lower()] + + if d_number == decimal.Decimal(0): + return 0 + + if d_number < 1 and "." in s_number: + with localcontext() as ctx: + multiplier = len(s_number) - s_number.index(".") - 1 + ctx.prec = multiplier + d_number = decimal.Decimal(value=number, context=ctx) * 10 ** multiplier + unit_value /= 10 ** multiplier + + with localcontext() as ctx: + ctx.prec = 999 + result_value = decimal.Decimal(value=d_number, context=ctx) * unit_value + + if result_value < MIN_WEI or result_value > MAX_WEI: + raise ValueError("Resulting wei value must be between 1 and 2**256 - 1") + + return int(result_value) diff --git a/client_sdk_python/packages/eth_utils/curried/__init__.py b/client_sdk_python/packages/eth_utils/curried/__init__.py new file mode 100644 index 0000000..6c1cefb --- /dev/null +++ b/client_sdk_python/packages/eth_utils/curried/__init__.py @@ -0,0 +1,101 @@ +# flake8: noqa +from client_sdk_python.packages.eth_utils import ( + ExtendedDebugLogger, + HasExtendedDebugLogger, + HasExtendedDebugLoggerMeta, + HasLogger, + HasLoggerMeta, + ValidationError, + add_0x_prefix, + apply_formatter_at_index, + apply_formatter_if, + apply_formatter_to_array, + apply_formatters_to_dict, + apply_formatters_to_sequence, + apply_key_map, + apply_one_of_formatters, + apply_to_return_value, + big_endian_to_int, + clamp, + combine_argument_formatters, + combomethod, + decode_hex, + denoms, + encode_hex, + event_abi_to_log_topic, + event_signature_to_log_topic, + flatten_return, + from_wei, + function_abi_to_4byte_selector, + function_signature_to_4byte_selector, + get_extended_debug_logger, + get_logger, + hexstr_if_str, + humanize_bytes, + humanize_hash, + humanize_integer_sequence, + humanize_ipfs_uri, + humanize_seconds, + import_string, + int_to_big_endian, + is_0x_prefixed, + is_address, + is_binary_address, + is_boolean, + is_bytes, + is_canonical_address, + is_checksum_address, + is_checksum_formatted_address, + is_dict, + is_hex, + is_hex_address, + is_hexstr, + is_integer, + is_list, + is_list_like, + is_normalized_address, + is_null, + is_number, + is_same_address, + is_string, + is_text, + is_tuple, + keccak, + remove_0x_prefix, + replace_exceptions, + reversed_return, + setup_DEBUG2_logging, + sort_return, + text_if_str, + to_bytes, + to_canonical_address, + to_checksum_address, + to_dict, + to_hex, + to_int, + to_list, + to_normalized_address, + to_ordered_dict, + to_set, + to_text, + to_tuple, + to_wei, +) +from client_sdk_python.packages.eth_utils.toolz import curry + +apply_formatter_at_index = curry(apply_formatter_at_index) +apply_formatter_if = curry(apply_formatter_if) +apply_formatter_to_array = curry(apply_formatter_to_array) +apply_formatters_to_dict = curry(apply_formatters_to_dict) +apply_formatters_to_sequence = curry(apply_formatters_to_sequence) +apply_key_map = curry(apply_key_map) +apply_one_of_formatters = curry(apply_one_of_formatters) +from_wei = curry(from_wei) +get_logger = curry(get_logger) +hexstr_if_str = curry(hexstr_if_str) +is_same_address = curry(is_same_address) +text_if_str = curry(text_if_str) +to_wei = curry(to_wei) +clamp = curry(clamp) + +del curry diff --git a/client_sdk_python/packages/eth_utils/curried/__init__.pyi b/client_sdk_python/packages/eth_utils/curried/__init__.pyi new file mode 100644 index 0000000..65789cd --- /dev/null +++ b/client_sdk_python/packages/eth_utils/curried/__init__.pyi @@ -0,0 +1,110 @@ +from typing import Any, Callable, Sequence, Tuple, TypeVar, Union, overload + +from eth_utils.curried import ( + ExtendedDebugLogger, + HasExtendedDebugLogger, + HasExtendedDebugLoggerMeta, + HasLogger, + HasLoggerMeta, + ValidationError, + add_0x_prefix, + apply_formatter_at_index, + apply_formatter_if, + apply_formatter_to_array, + apply_formatters_to_dict, + apply_formatters_to_sequence, + apply_key_map, + apply_one_of_formatters, + apply_to_return_value, + big_endian_to_int, + clamp, + combine_argument_formatters, + combomethod, + decode_hex, + denoms, + encode_hex, + event_abi_to_log_topic, + event_signature_to_log_topic, + flatten_return, + from_wei, + function_abi_to_4byte_selector, + function_signature_to_4byte_selector, + get_extended_debug_logger, + get_logger, + hexstr_if_str, + humanize_hash, + humanize_ipfs_uri, + humanize_seconds, + import_string, + int_to_big_endian, + is_0x_prefixed, + is_address, + is_binary_address, + is_boolean, + is_bytes, + is_canonical_address, + is_checksum_address, + is_checksum_formatted_address, + is_dict, + is_hex, + is_hex_address, + is_hexstr, + is_integer, + is_list, + is_list_like, + is_normalized_address, + is_null, + is_number, + is_same_address, + is_string, + is_text, + is_tuple, + keccak, + remove_0x_prefix, + replace_exceptions, + reversed_return, + setup_DEBUG2_logging, + sort_return, + text_if_str, + to_bytes, + to_canonical_address, + to_checksum_address, + to_dict, + to_hex, + to_int, + to_list, + to_normalized_address, + to_ordered_dict, + to_set, + to_text, + to_tuple, + to_wei, +) + +TReturn = TypeVar("TReturn") +TValue = TypeVar("TValue") +@overload +def apply_formatter_if( + condition: Callable[..., bool] +) -> Callable[[Callable[..., TReturn]], Callable[[TValue], Union[TReturn, TValue]]]: ... +@overload +def apply_formatter_if( + condition: Callable[..., bool], formatter: Callable[..., TReturn] +) -> Callable[[TValue], Union[TReturn, TValue]]: ... +@overload +def apply_formatter_if( + condition: Callable[..., bool], formatter: Callable[..., TReturn], value: TValue +) -> Union[TReturn, TValue]: ... +@overload +def apply_one_of_formatters( + formatter_condition_pairs: Sequence[ + Tuple[Callable[..., bool], Callable[..., TReturn]], ... + ] +) -> Callable[[TValue], TReturn]: ... +@overload +def apply_one_of_formatters( + formatter_condition_pairs: Sequence[ + Tuple[Callable[..., bool], Callable[..., TReturn]], ... + ], + value: TValue, +) -> TReturn: ... diff --git a/client_sdk_python/packages/eth_utils/debug.py b/client_sdk_python/packages/eth_utils/debug.py new file mode 100644 index 0000000..d77e84c --- /dev/null +++ b/client_sdk_python/packages/eth_utils/debug.py @@ -0,0 +1,20 @@ +import platform +import subprocess +import sys + + +def pip_freeze() -> str: + result = subprocess.run("pip freeze".split(), stdout=subprocess.PIPE) + return "pip freeze result:\n%s" % result.stdout.decode() + + +def python_version() -> str: + return "Python version:\n%s" % sys.version + + +def platform_info() -> str: + return "Operating System: %s" % platform.platform() + + +def get_environment_summary() -> str: + return "\n\n".join([python_version(), platform_info(), pip_freeze()]) diff --git a/client_sdk_python/packages/eth_utils/decorators.py b/client_sdk_python/packages/eth_utils/decorators.py new file mode 100644 index 0000000..b46c187 --- /dev/null +++ b/client_sdk_python/packages/eth_utils/decorators.py @@ -0,0 +1,125 @@ +import functools +import itertools +from typing import Any, Callable, Dict, Iterable, Type, TypeVar + +from .types import is_text + +T = TypeVar("T") + + +class combomethod(object): + def __init__(self, method: Callable[..., Any]) -> None: + self.method = method + + def __get__(self, obj: T = None, objtype: Type[T] = None) -> Callable[..., Any]: + @functools.wraps(self.method) + def _wrapper(*args: Any, **kwargs: Any) -> Any: + if obj is not None: + return self.method(obj, *args, **kwargs) + else: + return self.method(objtype, *args, **kwargs) + + return _wrapper + + +def _has_one_val(*args: T, **kwargs: T) -> bool: + vals = itertools.chain(args, kwargs.values()) + not_nones = list(filter(lambda val: val is not None, vals)) + return len(not_nones) == 1 + + +def _assert_one_val(*args: T, **kwargs: T) -> None: + if not _has_one_val(*args, **kwargs): + raise TypeError( + "Exactly one of the passed values can be specified. " + "Instead, values were: %r, %r" % (args, kwargs) + ) + + +def _hexstr_or_text_kwarg_is_text_type(**kwargs: T) -> bool: + value = kwargs["hexstr"] if "hexstr" in kwargs else kwargs["text"] + return is_text(value) + + +def _assert_hexstr_or_text_kwarg_is_text_type(**kwargs: T) -> None: + if not _hexstr_or_text_kwarg_is_text_type(**kwargs): + raise TypeError( + "Arguments passed as hexstr or text must be of text type. " + "Instead, value was: %r" % (repr(next(iter(list(kwargs.values()))))) + ) + + +def _validate_supported_kwarg(kwargs: Any) -> None: + if next(iter(kwargs)) not in ["primitive", "hexstr", "text"]: + raise TypeError( + "Kwarg must be 'primitive', 'hexstr', or 'text'. " + "Instead, kwarg was: %r" % (next(iter(kwargs))) + ) + + +def validate_conversion_arguments(to_wrap: Callable[..., T]) -> Callable[..., T]: + """ + Validates arguments for conversion functions. + - Only a single argument is present + - Kwarg must be 'primitive' 'hexstr' or 'text' + - If it is 'hexstr' or 'text' that it is a text type + """ + + @functools.wraps(to_wrap) + def wrapper(*args: Any, **kwargs: Any) -> T: + _assert_one_val(*args, **kwargs) + if kwargs: + _validate_supported_kwarg(kwargs) + + if len(args) == 0 and "primitive" not in kwargs: + _assert_hexstr_or_text_kwarg_is_text_type(**kwargs) + return to_wrap(*args, **kwargs) + + return wrapper + + +def return_arg_type(at_position: int) -> Callable[..., Callable[..., T]]: + """ + Wrap the return value with the result of `type(args[at_position])` + """ + + def decorator(to_wrap: Callable[..., Any]) -> Callable[..., T]: + @functools.wraps(to_wrap) + def wrapper(*args: Any, **kwargs: Any) -> T: + result = to_wrap(*args, **kwargs) + ReturnType = type(args[at_position]) + return ReturnType(result) + + return wrapper + + return decorator + + +def replace_exceptions( + old_to_new_exceptions: Dict[Type[BaseException], Type[BaseException]] +) -> Callable[..., Any]: + """ + Replaces old exceptions with new exceptions to be raised in their place. + """ + old_exceptions = tuple(old_to_new_exceptions.keys()) + + def decorator(to_wrap: Callable[..., Any]) -> Callable[..., Any]: + @functools.wraps(to_wrap) + # String type b/c pypy3 throws SegmentationFault with Iterable as arg on nested fn + # Ignore so we don't have to import `Iterable` + def wrapper( + *args: Iterable[Any], **kwargs: Dict[str, Any] + ) -> Callable[..., Any]: + try: + return to_wrap(*args, **kwargs) + except old_exceptions as err: + try: + raise old_to_new_exceptions[type(err)] from err + except KeyError: + raise TypeError( + "could not look up new exception to use for %r" % err + ) from err + + return wrapper + + return decorator diff --git a/client_sdk_python/packages/eth_utils/encoding.py b/client_sdk_python/packages/eth_utils/encoding.py new file mode 100644 index 0000000..44a9fe7 --- /dev/null +++ b/client_sdk_python/packages/eth_utils/encoding.py @@ -0,0 +1,6 @@ +def int_to_big_endian(value: int) -> bytes: + return value.to_bytes((value.bit_length() + 7) // 8 or 1, "big") + + +def big_endian_to_int(value: bytes) -> int: + return int.from_bytes(value, "big") diff --git a/client_sdk_python/packages/eth_utils/exceptions.py b/client_sdk_python/packages/eth_utils/exceptions.py new file mode 100644 index 0000000..8d8af44 --- /dev/null +++ b/client_sdk_python/packages/eth_utils/exceptions.py @@ -0,0 +1,6 @@ +class ValidationError(Exception): + """ + Raised when something does not pass a validation check. + """ + + pass diff --git a/client_sdk_python/packages/eth_utils/functional.py b/client_sdk_python/packages/eth_utils/functional.py new file mode 100644 index 0000000..ae49a7c --- /dev/null +++ b/client_sdk_python/packages/eth_utils/functional.py @@ -0,0 +1,73 @@ +import collections +import functools +import itertools +from typing import ( # noqa: F401 + Any, + Callable, + Dict, + Iterable, + List, + Mapping, + Set, + Tuple, + TypeVar, + Union, +) + +from .toolz import compose as _compose + +T = TypeVar("T") + + +def identity(value: T) -> T: + return value + + +TGIn = TypeVar("TGIn") +TGOut = TypeVar("TGOut") +TFOut = TypeVar("TFOut") + + +def combine( + f: Callable[[TGOut], TFOut], g: Callable[[TGIn], TGOut] +) -> Callable[[TGIn], TFOut]: + return lambda x: f(g(x)) + + +def apply_to_return_value( + callback: Callable[..., T] +) -> Callable[..., Callable[..., T]]: + def outer(fn: Callable[..., T]) -> Callable[..., T]: + # We would need to type annotate *args and **kwargs but doing so segfaults + # the PyPy builds. We ignore instead. + @functools.wraps(fn) + def inner(*args, **kwargs) -> T: # type: ignore + return callback(fn(*args, **kwargs)) + + return inner + + return outer + + +TVal = TypeVar("TVal") +TKey = TypeVar("TKey") +to_tuple = apply_to_return_value( + tuple +) # type: Callable[[Callable[..., Iterable[TVal]]], Callable[..., Tuple[TVal, ...]]] # noqa: E501 +to_list = apply_to_return_value( + list +) # type: Callable[[Callable[..., Iterable[TVal]]], Callable[..., List[TVal]]] # noqa: E501 +to_set = apply_to_return_value( + set +) # type: Callable[[Callable[..., Iterable[TVal]]], Callable[..., Set[TVal]]] # noqa: E501 +to_dict = apply_to_return_value( + dict +) # type: Callable[[Callable[..., Iterable[Union[Mapping[TKey, TVal], Tuple[TKey, TVal]]]]], Callable[..., Dict[TKey, TVal]]] # noqa: E501 +to_ordered_dict = apply_to_return_value( + collections.OrderedDict +) # type: Callable[[Callable[..., Iterable[Union[Mapping[TKey, TVal], Tuple[TKey, TVal]]]]], Callable[..., collections.OrderedDict[TKey, TVal]]] # noqa: E501 +sort_return = _compose(to_tuple, apply_to_return_value(sorted)) +flatten_return = _compose( + to_tuple, apply_to_return_value(itertools.chain.from_iterable) +) +reversed_return = _compose(to_tuple, apply_to_return_value(reversed), to_tuple) diff --git a/client_sdk_python/packages/eth_utils/hexadecimal.py b/client_sdk_python/packages/eth_utils/hexadecimal.py new file mode 100644 index 0000000..64320f9 --- /dev/null +++ b/client_sdk_python/packages/eth_utils/hexadecimal.py @@ -0,0 +1,102 @@ +# String encodings and numeric representations + +import binascii +import codecs +import re +import string +from typing import Any, AnyStr +import warnings + +from eth_typing import HexStr + +from .types import is_string, is_text + +_HEX_REGEXP = re.compile("[0-9a-fA-F]*") + + +# Type ignored for `codecs.decode()` due to lack of mypy support for 'hex' encoding +# https://github.com/python/typeshed/issues/300 +def decode_hex(value: str) -> bytes: + if not is_text(value): + raise TypeError("Value must be an instance of str") + return codecs.decode(remove_0x_prefix(value), "hex") # type: ignore #codecs.decode(remove_0x_prefix(value), "hex") + + +def encode_hex(value: AnyStr) -> HexStr: + if not is_string(value): + raise TypeError("Value must be an instance of str or unicode") + binary_hex = codecs.encode(value, "hex") # type: ignore + return add_0x_prefix(HexStr(binary_hex.decode("ascii"))) + + +def is_0x_prefixed(value: Any) -> bool: + if not is_text(value): + raise TypeError( + "is_0x_prefixed requires text typed arguments. Got: {0}".format(repr(value)) + ) + return value.startswith("0x") or value.startswith("0X") + + +def remove_0x_prefix(value: HexStr) -> HexStr: + if is_0x_prefixed(value): + return HexStr(value[2:]) + return value + + +def add_0x_prefix(value: HexStr) -> HexStr: + if is_0x_prefixed(value): + return value + return HexStr("0x" + value) + + +def is_hexstr(value: Any) -> bool: + if not is_text(value): + return False + + elif value.lower() == "0x": + return True + + unprefixed_value = remove_0x_prefix(value) + if len(unprefixed_value) % 2 != 0: + value_to_decode = "0" + unprefixed_value + else: + value_to_decode = unprefixed_value + + if not _HEX_REGEXP.fullmatch(value_to_decode): + return False + + try: + value_as_bytes = codecs.decode(value_to_decode, "hex") # type: ignore + except binascii.Error: + return False + except TypeError: + return False + else: + return bool(value_as_bytes) + + +def is_hex(value: Any) -> bool: + if not is_text(value): + raise TypeError( + "is_hex requires text typed arguments. Got: {0}".format(repr(value)) + ) + elif value.lower() == "0x": + return True + + unprefixed_value = remove_0x_prefix(value) + if len(unprefixed_value) % 2 != 0: + value_to_decode = "0" + unprefixed_value + else: + value_to_decode = unprefixed_value + + if not _HEX_REGEXP.fullmatch(value_to_decode): + return False + + try: + value_as_bytes = codecs.decode(value_to_decode, "hex") # type: ignore + except binascii.Error: + return False + except TypeError: + return False + else: + return bool(value_as_bytes) diff --git a/client_sdk_python/packages/eth_utils/humanize.py b/client_sdk_python/packages/eth_utils/humanize.py new file mode 100644 index 0000000..03dd95c --- /dev/null +++ b/client_sdk_python/packages/eth_utils/humanize.py @@ -0,0 +1,159 @@ +from typing import Any, Iterable, Iterator, Tuple, Union +from urllib import parse + +from eth_typing import URI, Hash32 + +from .toolz import sliding_window, take + + +def humanize_seconds(seconds: Union[float, int]) -> str: + if int(seconds) == 0: + return "0s" + + unit_values = _consume_leading_zero_units(_humanize_seconds(int(seconds))) + + return "".join( + ("{0}{1}".format(amount, unit) for amount, unit in take(3, unit_values)) + ) + + +SECOND = 1 +MINUTE = 60 +HOUR = 60 * 60 +DAY = 24 * HOUR +YEAR = 365 * DAY +MONTH = YEAR // 12 +WEEK = 7 * DAY + + +UNITS = ( + (YEAR, "y"), + (MONTH, "m"), + (WEEK, "w"), + (DAY, "d"), + (HOUR, "h"), + (MINUTE, "m"), + (SECOND, "s"), +) + + +def _consume_leading_zero_units( + units_iter: Iterator[Tuple[int, str]] +) -> Iterator[Tuple[int, str]]: + for amount, unit in units_iter: + if amount == 0: + continue + else: + yield (amount, unit) + break + + yield from units_iter + + +def _humanize_seconds(seconds: int) -> Iterator[Tuple[int, str]]: + remainder = seconds + + for duration, unit in UNITS: + if not remainder: + break + + num = remainder // duration + yield num, unit + + remainder %= duration + + +DISPLAY_HASH_CHARS = 4 + + +def humanize_bytes(value: bytes) -> str: + if len(value) <= DISPLAY_HASH_CHARS + 1: + return value.hex() + value_as_hex = value.hex() + head = value_as_hex[:DISPLAY_HASH_CHARS] + tail = value_as_hex[-1 * DISPLAY_HASH_CHARS :] + return "{0}..{1}".format(head, tail) + + +def humanize_hash(value: Hash32) -> str: + return humanize_bytes(value) + + +def humanize_ipfs_uri(uri: URI) -> str: + if not is_ipfs_uri(uri): + raise TypeError( + "%s does not look like a valid IPFS uri. Currently, " + "only CIDv0 hash schemes are supported." % uri + ) + + parsed = parse.urlparse(uri) + ipfs_hash = parsed.netloc + head = ipfs_hash[:DISPLAY_HASH_CHARS] + tail = ipfs_hash[-1 * DISPLAY_HASH_CHARS :] + return "ipfs://{0}..{1}".format(head, tail) + + +def is_ipfs_uri(value: Any) -> bool: + if not isinstance(value, str): + return False + + parsed = parse.urlparse(value) + if parsed.scheme != "ipfs" or not parsed.netloc: + return False + + return _is_CIDv0_ipfs_hash(parsed.netloc) + + +def _is_CIDv0_ipfs_hash(ipfs_hash: str) -> bool: + if ipfs_hash.startswith("Qm") and len(ipfs_hash) == 46: + return True + return False + + +def _find_breakpoints(*values: int) -> Iterator[int]: + yield 0 + for index, (left, right) in enumerate(sliding_window(2, values), 1): + if left + 1 == right: + continue + else: + yield index + yield len(values) + + +def _extract_integer_ranges(*values: int) -> Iterator[Tuple[int, int]]: + """ + Take a sequence of integers which is expected to be ordered and return the + most concise definition of the sequence in terms of integer ranges. + + - fn(1, 2, 3) -> ((1, 3),) + - fn(1, 2, 3, 7, 8, 9) -> ((1, 3), (7, 9)) + - fn(1, 7, 8, 9) -> ((1, 1), (7, 9)) + """ + for left, right in sliding_window(2, _find_breakpoints(*values)): + chunk = values[left:right] + yield chunk[0], chunk[-1] + + +def _humanize_range(bounds: Tuple[int, int]) -> str: + left, right = bounds + if left == right: + return str(left) + else: + return "{left}-{right}".format(left=left, right=right) + + +def humanize_integer_sequence(values_iter: Iterable[int]) -> str: + """ + Return a human readable string that attempts to concisely define a sequence + of integers. + + - fn((1, 2, 3)) -> '1-3' + - fn((1, 2, 3, 7, 8, 9)) -> '1-3|7-9' + - fn((1, 2, 3, 5, 7, 8, 9)) -> '1-3|5|7-9' + - fn((1, 7, 8, 9)) -> '1|7-9' + """ + values = tuple(values_iter) + if not values: + return "(empty)" + else: + return "|".join(map(_humanize_range, _extract_integer_ranges(*values))) diff --git a/client_sdk_python/packages/eth_utils/logging.py b/client_sdk_python/packages/eth_utils/logging.py new file mode 100644 index 0000000..ed42293 --- /dev/null +++ b/client_sdk_python/packages/eth_utils/logging.py @@ -0,0 +1,153 @@ +import contextlib +import functools +import logging +from typing import Any, Callable, Dict, Iterator, Optional, Tuple, Type, TypeVar, cast + +from .toolz import assoc + +DEBUG2_LEVEL_NUM = 8 + +TLogger = TypeVar("TLogger", bound=logging.Logger) + + +class cached_show_debug2_property: + def __init__(self, func: Callable[[TLogger], bool]): + # type ignored b/c arg1 expects Callable[..., Any] + functools.update_wrapper(self, func) # type: ignore + self._func = func + + def __get__(self, obj: Optional[TLogger], cls: Type[logging.Logger]) -> Any: + if obj is None: + return self + + result = self._func(obj) + obj.__dict__[self._func.__name__] = result + return result + + +class ExtendedDebugLogger(logging.Logger): + """ + Logging class that can be used for lower level debug logging. + """ + + @cached_show_debug2_property + def show_debug2(self) -> bool: + return self.isEnabledFor(DEBUG2_LEVEL_NUM) + + def debug2(self, message: str, *args: Any, **kwargs: Any) -> None: + if self.show_debug2: + self.log(DEBUG2_LEVEL_NUM, message, *args, **kwargs) + else: + # When we find that `DEBUG2` isn't enabled we completely replace + # the `debug2` function in this instance of the logger with a noop + # lambda to further speed up + self.__dict__["debug2"] = lambda message, *args, **kwargs: None + + +def setup_DEBUG2_logging() -> None: + """ + Installs the `DEBUG2` level logging levels to the main logging module. + """ + if not hasattr(logging, "DEBUG2"): + logging.addLevelName(DEBUG2_LEVEL_NUM, "DEBUG2") + setattr(logging, "DEBUG2", DEBUG2_LEVEL_NUM) # typing: ignore + + +@contextlib.contextmanager +def _use_logger_class(logger_class: Type[logging.Logger]) -> Iterator[None]: + original_logger_class = logging.getLoggerClass() + logging.setLoggerClass(logger_class) + try: + yield + finally: + logging.setLoggerClass(original_logger_class) + + +def get_logger(name: str, logger_class: Type[TLogger] = None) -> TLogger: + if logger_class is None: + return cast(TLogger, logging.getLogger(name)) + else: + with _use_logger_class(logger_class): + # The logging module caches logger instances. The following code + # ensures that if there is a cached instance that we don't + # accidentally return the incorrect logger type because the logging + # module does not *update* the cached instance in the event that + # the global logging class changes. + # + # types ignored b/c mypy doesn't identify presence of manager on logging.Logger + manager = logging.Logger.manager # type: ignore + if name in manager.loggerDict: + if type(manager.loggerDict[name]) is not logger_class: + del manager.loggerDict[name] + return cast(TLogger, logging.getLogger(name)) + + +def get_extended_debug_logger(name: str) -> ExtendedDebugLogger: + return get_logger(name, ExtendedDebugLogger) + + +THasLoggerMeta = TypeVar("THasLoggerMeta", bound="HasLoggerMeta") + + +class HasLoggerMeta(type): + """ + Metaclass which using the `__qualname__` to assign a logger instance to the + class who's name corresponds to the import path for the class. + """ + + logger_class = logging.Logger + + def __new__( + mcls: Type[THasLoggerMeta], + name: str, + bases: Tuple[Type[Any]], + namespace: Dict[str, Any], + ) -> type: + if "logger" in namespace: + # If a logger was explicitly declared we shouldn't do anything to + # replace it. + return super().__new__(mcls, name, bases, namespace) + if "__qualname__" not in namespace: + raise AttributeError("Missing __qualname__") + + with _use_logger_class(mcls.logger_class): + logger = logging.getLogger(namespace["__qualname__"]) + + return super().__new__(mcls, name, bases, assoc(namespace, "logger", logger)) + + @classmethod + def replace_logger_class( + mcls: Type[THasLoggerMeta], value: Type[logging.Logger] + ) -> Type[THasLoggerMeta]: + return type(mcls.__name__, (mcls,), {"logger_class": value}) + + @classmethod + def meta_compat( + mcls: Type[THasLoggerMeta], other: Type[type] + ) -> Type[THasLoggerMeta]: + return type(mcls.__name__, (mcls, other), {}) + + +class _BaseHasLogger(metaclass=HasLoggerMeta): + # This class exists to a allow us to define the type of the logger. Once + # python3.5 is deprecated this can be removed in favor of a simple type + # annotation on the main class. + logger = logging.Logger("") # type: logging.Logger + + +class HasLogger(_BaseHasLogger): + pass + + +HasExtendedDebugLoggerMeta = HasLoggerMeta.replace_logger_class(ExtendedDebugLogger) + + +class _BaseHasExtendedDebugLogger(metaclass=HasExtendedDebugLoggerMeta): # type: ignore + # This class exists to a allow us to define the type of the logger. Once + # python3.5 is deprecated this can be removed in favor of a simple type + # annotation on the main class. + logger = ExtendedDebugLogger("") # type: ExtendedDebugLogger + + +class HasExtendedDebugLogger(_BaseHasExtendedDebugLogger): + pass diff --git a/client_sdk_python/packages/eth_utils/module_loading.py b/client_sdk_python/packages/eth_utils/module_loading.py new file mode 100644 index 0000000..33822db --- /dev/null +++ b/client_sdk_python/packages/eth_utils/module_loading.py @@ -0,0 +1,26 @@ +from importlib import import_module +from typing import Any + + +def import_string(dotted_path: str) -> Any: + """ + Source: django.utils.module_loading + Import a dotted module path and return the attribute/class designated by the + last name in the path. Raise ImportError if the import failed. + """ + try: + module_path, class_name = dotted_path.rsplit(".", 1) + except ValueError: + msg = "%s doesn't look like a module path" % dotted_path + raise ImportError(msg) + + module = import_module(module_path) + + try: + return getattr(module, class_name) + except AttributeError: + msg = 'Module "%s" does not define a "%s" attribute/class' % ( + module_path, + class_name, + ) + raise ImportError(msg) diff --git a/client_sdk_python/packages/eth_utils/numeric.py b/client_sdk_python/packages/eth_utils/numeric.py new file mode 100644 index 0000000..526a68c --- /dev/null +++ b/client_sdk_python/packages/eth_utils/numeric.py @@ -0,0 +1,36 @@ +from abc import ABC, abstractmethod +import decimal +import numbers +from typing import Any, TypeVar, Union + + +class Comparable(ABC): + @abstractmethod + def __lt__(self, other: Any) -> bool: + ... + + @abstractmethod + def __gt__(self, other: Any) -> bool: + ... + + +TComparable = Union[Comparable, numbers.Real, int, float, decimal.Decimal] + + +TValue = TypeVar("TValue", bound=TComparable) + + +def clamp(lower_bound: TValue, upper_bound: TValue, value: TValue) -> TValue: + # The `mypy` ignore statements here are due to doing a comparison of + # `Union` types which isn't allowed. (per cburgdorf). This approach was + # chosen over using `typing.overload` to define multiple signatures for + # each comparison type here since the added value of "proper" typing + # doesn't seem to justify the complexity of having a bunch of different + # signatures defined. The external library perspective on this function + # should still be adequate under this approach + if value < lower_bound: # type: ignore + return lower_bound + elif value > upper_bound: # type: ignore + return upper_bound + else: + return value diff --git a/client_sdk_python/packages/eth_utils/py.typed b/client_sdk_python/packages/eth_utils/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/client_sdk_python/packages/eth_utils/toolz.py b/client_sdk_python/packages/eth_utils/toolz.py new file mode 100644 index 0000000..683f1b6 --- /dev/null +++ b/client_sdk_python/packages/eth_utils/toolz.py @@ -0,0 +1,156 @@ +try: + from cytoolz import ( + accumulate, + assoc, + assoc_in, + comp, + compatibility, + complement, + compose, + concat, + concatv, + cons, + count, + countby, + curried, + curry, + dicttoolz, + diff, + dissoc, + do, + drop, + excepts, + filter, + first, + flip, + frequencies, + functoolz, + get, + get_in, + groupby, + identity, + interleave, + interpose, + isdistinct, + isiterable, + itemfilter, + itemmap, + iterate, + itertoolz, + join, + juxt, + keyfilter, + keymap, + last, + map, + mapcat, + memoize, + merge, + merge_sorted, + merge_with, + nth, + partial, + partition, + partition_all, + partitionby, + peek, + pipe, + pluck, + random_sample, + recipes, + reduce, + reduceby, + remove, + second, + sliding_window, + sorted, + tail, + take, + take_nth, + thread_first, + thread_last, + topk, + unique, + update_in, + utils, + valfilter, + valmap, + ) +except ImportError: + from toolz import ( # noqa: F401 + accumulate, + assoc, + assoc_in, + comp, + compatibility, + complement, + compose, + concat, + concatv, + cons, + count, + countby, + curried, + curry, + dicttoolz, + diff, + dissoc, + do, + drop, + excepts, + filter, + first, + flip, + frequencies, + functoolz, + get, + get_in, + groupby, + identity, + interleave, + interpose, + isdistinct, + isiterable, + itemfilter, + itemmap, + iterate, + itertoolz, + join, + juxt, + keyfilter, + keymap, + last, + map, + mapcat, + memoize, + merge, + merge_sorted, + merge_with, + nth, + partial, + partition, + partition_all, + partitionby, + peek, + pipe, + pluck, + random_sample, + recipes, + reduce, + reduceby, + remove, + second, + sliding_window, + sorted, + tail, + take, + take_nth, + thread_first, + thread_last, + topk, + unique, + update_in, + utils, + valfilter, + valmap, + ) diff --git a/client_sdk_python/packages/eth_utils/types.py b/client_sdk_python/packages/eth_utils/types.py new file mode 100644 index 0000000..b63f048 --- /dev/null +++ b/client_sdk_python/packages/eth_utils/types.py @@ -0,0 +1,52 @@ +import collections.abc +import numbers +from typing import Any + +bytes_types = (bytes, bytearray) +integer_types = (int,) +text_types = (str,) +string_types = (bytes, str, bytearray) + + +def is_integer(value: Any) -> bool: + return isinstance(value, integer_types) and not isinstance(value, bool) + + +def is_bytes(value: Any) -> bool: + return isinstance(value, bytes_types) + + +def is_text(value: Any) -> bool: + return isinstance(value, text_types) + + +def is_string(value: Any) -> bool: + return isinstance(value, string_types) + + +def is_boolean(value: Any) -> bool: + return isinstance(value, bool) + + +def is_dict(obj: Any) -> bool: + return isinstance(obj, collections.Mapping) + + +def is_list_like(obj: Any) -> bool: + return not is_string(obj) and isinstance(obj, collections.abc.Sequence) + + +def is_list(obj: Any) -> bool: + return isinstance(obj, list) + + +def is_tuple(obj: Any) -> bool: + return isinstance(obj, tuple) + + +def is_null(obj: Any) -> bool: + return obj is None + + +def is_number(obj: Any) -> bool: + return isinstance(obj, numbers.Number) diff --git a/client_sdk_python/packages/eth_utils/typing/__init__.py b/client_sdk_python/packages/eth_utils/typing/__init__.py new file mode 100644 index 0000000..60f0e83 --- /dev/null +++ b/client_sdk_python/packages/eth_utils/typing/__init__.py @@ -0,0 +1,18 @@ +import warnings + +from .misc import ( # noqa: F401 + Address, + AnyAddress, + ChecksumAddress, + HexAddress, + HexStr, + Primitives, + T, +) + +warnings.warn( + "The eth_utils.typing module will be deprecated in favor " + "of eth-typing in the next major version bump.", + category=DeprecationWarning, + stacklevel=2, +) diff --git a/client_sdk_python/packages/eth_utils/typing/misc.py b/client_sdk_python/packages/eth_utils/typing/misc.py new file mode 100644 index 0000000..45cfc91 --- /dev/null +++ b/client_sdk_python/packages/eth_utils/typing/misc.py @@ -0,0 +1,12 @@ +from typing import TypeVar + +from eth_typing import ( # noqa: F401 + Address, + AnyAddress, + ChecksumAddress, + HexAddress, + HexStr, + Primitives, +) + +T = TypeVar("T") diff --git a/client_sdk_python/packages/eth_utils/units.py b/client_sdk_python/packages/eth_utils/units.py new file mode 100644 index 0000000..8848b89 --- /dev/null +++ b/client_sdk_python/packages/eth_utils/units.py @@ -0,0 +1,31 @@ +import decimal + +# Units are in their own module here, so that they can keep this +# formatting, as this module is excluded from black in pyproject.toml +# fmt: off +units = { + 'wei': decimal.Decimal('1'), # noqa: E241 + 'kwei': decimal.Decimal('1000'), # noqa: E241 + 'babbage': decimal.Decimal('1000'), # noqa: E241 + 'femtoether': decimal.Decimal('1000'), # noqa: E241 + 'mwei': decimal.Decimal('1000000'), # noqa: E241 + 'lovelace': decimal.Decimal('1000000'), # noqa: E241 + 'picoether': decimal.Decimal('1000000'), # noqa: E241 + 'gwei': decimal.Decimal('1000000000'), # noqa: E241 + 'shannon': decimal.Decimal('1000000000'), # noqa: E241 + 'nanoether': decimal.Decimal('1000000000'), # noqa: E241 + 'nano': decimal.Decimal('1000000000'), # noqa: E241 + 'szabo': decimal.Decimal('1000000000000'), # noqa: E241 + 'microether': decimal.Decimal('1000000000000'), # noqa: E241 + 'micro': decimal.Decimal('1000000000000'), # noqa: E241 + 'finney': decimal.Decimal('1000000000000000'), # noqa: E241 + 'milliether': decimal.Decimal('1000000000000000'), # noqa: E241 + 'milli': decimal.Decimal('1000000000000000'), # noqa: E241 + 'ether': decimal.Decimal('1000000000000000000'), # noqa: E241 + 'kether': decimal.Decimal('1000000000000000000000'), # noqa: E241 + 'grand': decimal.Decimal('1000000000000000000000'), # noqa: E241 + 'mether': decimal.Decimal('1000000000000000000000000'), # noqa: E241 + 'gether': decimal.Decimal('1000000000000000000000000000'), # noqa: E241 + 'tether': decimal.Decimal('1000000000000000000000000000000'), # noqa: E241 +} +# fmt: on diff --git a/client_sdk_python/packages/platon_account/__init__.py b/client_sdk_python/packages/platon_account/__init__.py new file mode 100644 index 0000000..fd7a215 --- /dev/null +++ b/client_sdk_python/packages/platon_account/__init__.py @@ -0,0 +1 @@ +from client_sdk_python.packages.platon_account.account import Account # noqa: F401 diff --git a/client_sdk_python/packages/platon_account/account.py b/client_sdk_python/packages/platon_account/account.py new file mode 100644 index 0000000..36efeac --- /dev/null +++ b/client_sdk_python/packages/platon_account/account.py @@ -0,0 +1,473 @@ +from collections.abc import ( + Mapping, +) +import json +import os + +from cytoolz import ( + dissoc, +) +from client_sdk_python.packages.platon_keyfile import ( + create_keyfile_json, + decode_keyfile_json, +) +from client_sdk_python.packages.platon_keys import ( + KeyAPI, + keys, +) +from client_sdk_python.packages.platon_keys.utils.address import DEFAULTHRP +from client_sdk_python.packages.platon_keys.exceptions import ( + ValidationError, +) +from client_sdk_python.packages.eth_utils import ( + combomethod, + hexstr_if_str, + is_dict, + keccak, + text_if_str, + to_bytes, + to_int, +) +from hexbytes import ( + HexBytes, +) + +from client_sdk_python.packages.platon_account.datastructures import ( + AttributeDict, +) +from client_sdk_python.packages.platon_account.internal.signing import ( + hash_of_signed_transaction, + sign_message_hash, + sign_transaction_dict, + to_standard_signature_bytes, + to_standard_v, +) +from client_sdk_python.packages.platon_account.internal.transactions import ( + Transaction, + vrs_from, +) +from client_sdk_python.packages.platon_account.signers.local import ( + LocalAccount, +) + + +class Account(object): + ''' + This is the primary entry point for working with awake006 private keys. + + It does **not** require a connection to an awake006 node. + ''' + _keys = keys + + @combomethod + def create(self, extra_entropy='', net_type=DEFAULTHRP): + ''' + Creates a new private key, and returns it as a :class:`~platon_account.local.LocalAccount`. + + :param extra_entropy: Add extra randomness to whatever randomness your OS can provide + :type extra_entropy: str or bytes or int + :returns: an object with private key and convenience methods + + .. code-block:: python + + >>> from client_sdk_python.packages.platon_account import Account + >>> acct = Account.create('KEYSMASH FJAFJKLDSKF7JKFDJ 1530') + >>> acct.address + '0x5ce9454909639D2D17A3F753ce7d93fa0b9aB12E' + >>> acct.privateKey + b"\\xb2\\}\\xb3\\x1f\\xee\\xd9\\x12''\\xbf\\t9\\xdcv\\x9a\\x96VK-\\xe4\\xc4rm\\x03[6\\xec\\xf1\\xe5\\xb3d" + + # These methods are also available: signHash(), signTransaction(), encrypt() + # They correspond to the same-named methods in Account.* + # but without the private key argument + ''' + extra_key_bytes = text_if_str(to_bytes, extra_entropy) + key_bytes = keccak(os.urandom(32) + extra_key_bytes) + return self.privateKeyToAccount(key_bytes, net_type) + + @staticmethod + def decrypt(keyfile_json, password): + ''' + Decrypts a private key that was encrypted using an awake006 client or + :meth:`~Account.encrypt`. + + :param keyfile_json: The encrypted key + :type keyfile_json: dict or str + :param str password: The password that was used to encrypt the key + :returns: the raw private key + :rtype: ~hexbytes.main.HexBytes + + .. code-block:: python + + >>> encrypted = { + 'address': '5ce9454909639d2d17a3f753ce7d93fa0b9ab12e', + 'crypto': {'cipher': 'aes-128-ctr', + 'cipherparams': {'iv': '78f214584844e0b241b433d7c3bb8d5f'}, + 'ciphertext': 'd6dbb56e4f54ba6db2e8dc14df17cb7352fdce03681dd3f90ce4b6c1d5af2c4f', + 'kdf': 'pbkdf2', + 'kdfparams': {'c': 1000000, + 'dklen': 32, + 'prf': 'hmac-sha256', + 'salt': '45cf943b4de2c05c2c440ef96af914a2'}, + 'mac': 'f5e1af09df5ded25c96fcf075ada313fb6f79735a914adc8cb02e8ddee7813c3'}, + 'id': 'b812f3f9-78cc-462a-9e89-74418aa27cb0', + 'version': 3} + + >>> import getpass + >>> Account.decrypt(encrypted, getpass.getpass()) + HexBytes('0xb25c7db31feed9122727bf0939dc769a96564b2de4c4726d035b36ecf1e5b364') + + ''' + if isinstance(keyfile_json, str): + keyfile = json.loads(keyfile_json) + elif is_dict(keyfile_json): + keyfile = keyfile_json + else: + raise TypeError("The keyfile should be supplied as a JSON string, or a dictionary.") + password_bytes = text_if_str(to_bytes, password) + return HexBytes(decode_keyfile_json(keyfile, password_bytes)) + + @staticmethod + def encrypt(private_key, password): + ''' + Creates a dictionary with an encrypted version of your private key. + To import this keyfile into awake006 clients like geth and parity: + encode this dictionary with :func:`json.dumps` and save it to disk where your + client keeps key files. + + :param private_key: The raw private key + :type private_key: hex str, bytes, int or :class:`platon_keys.datatypes.PrivateKey` + :param str password: The password which you will need to unlock the account in your client + :returns: The data to use in your encrypted file + :rtype: dict + + .. code-block:: python + + >>> import getpass + >>> encrypted = Account.encrypt( + 0xb25c7db31feed9122727bf0939dc769a96564b2de4c4726d035b36ecf1e5b364, + getpass.getpass() + ) + + {'address': '5ce9454909639d2d17a3f753ce7d93fa0b9ab12e', + 'crypto': {'cipher': 'aes-128-ctr', + 'cipherparams': {'iv': '78f214584844e0b241b433d7c3bb8d5f'}, + 'ciphertext': 'd6dbb56e4f54ba6db2e8dc14df17cb7352fdce03681dd3f90ce4b6c1d5af2c4f', + 'kdf': 'pbkdf2', + 'kdfparams': {'c': 1000000, + 'dklen': 32, + 'prf': 'hmac-sha256', + 'salt': '45cf943b4de2c05c2c440ef96af914a2'}, + 'mac': 'f5e1af09df5ded25c96fcf075ada313fb6f79735a914adc8cb02e8ddee7813c3'}, + 'id': 'b812f3f9-78cc-462a-9e89-74418aa27cb0', + 'version': 3} + + >>> with open('my-keyfile', 'w') as f: + f.write(json.dumps(encrypted)) + ''' + if isinstance(private_key, keys.PrivateKey): + key_bytes = private_key.to_bytes() + else: + key_bytes = HexBytes(private_key) + + password_bytes = text_if_str(to_bytes, password) + assert len(key_bytes) == 32 + return create_keyfile_json(key_bytes, password_bytes) + + @combomethod + def privateKeyToAccount(self, private_key, net_type=DEFAULTHRP): + ''' + Returns a convenient object for working with the given private key. + + :param private_key: The raw private key + :type private_key: hex str, bytes, int or :class:`platon_keys.datatypes.PrivateKey` + :return: object with methods for signing and encrypting + :rtype: LocalAccount + + .. code-block:: python + + >>> acct = Account.privateKeyToAccount( + 0xb25c7db31feed9122727bf0939dc769a96564b2de4c4726d035b36ecf1e5b364) + >>> acct.address + '0x5ce9454909639D2D17A3F753ce7d93fa0b9aB12E' + >>> acct.privateKey + b"\\xb2\\}\\xb3\\x1f\\xee\\xd9\\x12''\\xbf\\t9\\xdcv\\x9a\\x96VK-\\xe4\\xc4rm\\x03[6\\xec\\xf1\\xe5\\xb3d" + + # These methods are also available: signHash(), signTransaction(), encrypt() + # They correspond to the same-named methods in Account.* + # but without the private key argument + ''' + key = self._parsePrivateKey(private_key) + return LocalAccount(key, self, net_type) + + @combomethod + def recoverHash(self, message_hash, vrs=None, signature=None): + ''' + Get the address of the account that signed the message with the given hash. + You must specify exactly one of: vrs or signature + + :param message_hash: the hash of the message that you want to verify + :type message_hash: hex str or bytes or int + :param vrs: the three pieces generated by an elliptic curve signature + :type vrs: tuple(v, r, s), each element is hex str, bytes or int + :param signature: signature bytes concatenated as r+s+v + :type signature: hex str or bytes or int + :returns: address of signer, hex-encoded & checksummed + :rtype: str + + .. code-block:: python + + >>> msg = "I♥SF" + >>> msghash = '0x1476abb745d423bf09273f1afd887d951181d25adc66c4834a70491911b7f750' + >>> vrs = ( + 28, + '0xe6ca9bba58c88611fad66a6ce8f996908195593807c4b38bd528d2cff09d4eb3', + '0x3e5bfbbf4d3e39b1a2fd816a7680c19ebebaf3a141b239934ad43cb33fcec8ce') + >>> Account.recoverHash(msghash, vrs=vrs) + '0x5ce9454909639D2D17A3F753ce7d93fa0b9aB12E' + + # All of these recover calls are equivalent: + + # variations on msghash + >>> msghash = b"\\x14v\\xab\\xb7E\\xd4#\\xbf\\t'?\\x1a\\xfd\\x88}\\x95\\x11\\x81\\xd2Z\\xdcf\\xc4\\x83JpI\\x19\\x11\\xb7\\xf7P" # noqa: E501 + >>> Account.recoverHash(msghash, vrs=vrs) + >>> msghash = 0x1476abb745d423bf09273f1afd887d951181d25adc66c4834a70491911b7f750 + >>> Account.recoverHash(msghash, vrs=vrs) + + # variations on vrs + >>> vrs = ( + '0x1c', + '0xe6ca9bba58c88611fad66a6ce8f996908195593807c4b38bd528d2cff09d4eb3', + '0x3e5bfbbf4d3e39b1a2fd816a7680c19ebebaf3a141b239934ad43cb33fcec8ce') + >>> Account.recoverHash(msghash, vrs=vrs) + >>> vrs = ( + b'\\x1c', + b'\\xe6\\xca\\x9b\\xbaX\\xc8\\x86\\x11\\xfa\\xd6jl\\xe8\\xf9\\x96\\x90\\x81\\x95Y8\\x07\\xc4\\xb3\\x8b\\xd5(\\xd2\\xcf\\xf0\\x9dN\\xb3', # noqa: E501 + b'>[\\xfb\\xbfM>9\\xb1\\xa2\\xfd\\x81jv\\x80\\xc1\\x9e\\xbe\\xba\\xf3\\xa1A\\xb29\\x93J\\xd4<\\xb3?\\xce\\xc8\\xce') # noqa: E501 + >>> Account.recoverHash(msghash, vrs=vrs) + >>> vrs = ( + 0x1c, + 0xe6ca9bba58c88611fad66a6ce8f996908195593807c4b38bd528d2cff09d4eb3, + 0x3e5bfbbf4d3e39b1a2fd816a7680c19ebebaf3a141b239934ad43cb33fcec8ce) + >>> Account.recoverHash(msghash, vrs=vrs) + + # variations on signature + >>> signature = '0xe6ca9bba58c88611fad66a6ce8f996908195593807c4b38bd528d2cff09d4eb33e5bfbbf4d3e39b1a2fd816a7680c19ebebaf3a141b239934ad43cb33fcec8ce1c' # noqa: E501 + >>> Account.recoverHash(msghash, signature=signature) + >>> signature = b'\\xe6\\xca\\x9b\\xbaX\\xc8\\x86\\x11\\xfa\\xd6jl\\xe8\\xf9\\x96\\x90\\x81\\x95Y8\\x07\\xc4\\xb3\\x8b\\xd5(\\xd2\\xcf\\xf0\\x9dN\\xb3>[\\xfb\\xbfM>9\\xb1\\xa2\\xfd\\x81jv\\x80\\xc1\\x9e\\xbe\\xba\\xf3\\xa1A\\xb29\\x93J\\xd4<\\xb3?\\xce\\xc8\\xce\\x1c' # noqa: E501 + >>> Account.recoverHash(msghash, signature=signature) + >>> signature = 0xe6ca9bba58c88611fad66a6ce8f996908195593807c4b38bd528d2cff09d4eb33e5bfbbf4d3e39b1a2fd816a7680c19ebebaf3a141b239934ad43cb33fcec8ce1c # noqa: E501 + >>> Account.recoverHash(msghash, signature=signature) + ''' + hash_bytes = HexBytes(message_hash) + if len(hash_bytes) != 32: + raise ValueError("The message hash must be exactly 32-bytes") + if vrs is not None: + v, r, s = map(hexstr_if_str(to_int), vrs) + v_standard = to_standard_v(v) + signature_obj = self._keys.Signature(vrs=(v_standard, r, s)) + elif signature is not None: + signature_bytes = HexBytes(signature) + signature_bytes_standard = to_standard_signature_bytes(signature_bytes) + signature_obj = self._keys.Signature(signature_bytes=signature_bytes_standard) + else: + raise TypeError("You must supply the vrs tuple or the signature bytes") + pubkey = signature_obj.recover_public_key_from_msg_hash(hash_bytes) + return pubkey.to_checksum_address() + + @combomethod + def recoverTransaction(self, serialized_transaction): + ''' + Get the address of the account that signed this transaction. + + :param serialized_transaction: the complete signed transaction + :type serialized_transaction: hex str, bytes or int + :returns: address of signer, hex-encoded & checksummed + :rtype: str + + .. code-block:: python + + >>> raw_transaction = '0xf86a8086d55698372431831e848094f0109fc8df283027b6285cc889f5aa624eac1f55843b9aca008025a009ebb6ca057a0535d6186462bc0b465b561c94a295bdb0621fc19208ab149a9ca0440ffd775ce91a833ab410777204d5341a6f9fa91216a6f3ee2c051fea6a0428', # noqa: E501 + >>> Account.recoverTransaction(raw_transaction) + '0x2c7536E3605D9C16a7a3D7b1898e529396a65c23' + ''' + txn_bytes = HexBytes(serialized_transaction) + txn = Transaction.from_bytes(txn_bytes) + msg_hash = hash_of_signed_transaction(txn) + return self.recoverHash(msg_hash, vrs=vrs_from(txn)) + + def setKeyBackend(self, backend): + ''' + Change the backend used by the underlying eth-keys library. + + *(The default is fine for most users)* + + :param backend: any backend that works in + `platon_keys.KeyApi(backend) `_ + + ''' + self._keys = KeyAPI(backend) + + @combomethod + def signHash(self, message_hash, private_key): + ''' + Sign the hash provided. + + .. WARNING:: *Never* sign a hash that you didn't generate, + it can be an arbitrary transaction. For example, it might + send all of your account's ether to an attacker. + + If you would like compatibility with + :meth:`w3.eth.sign() ` + you can use :meth:`~platon_account.messages.defunct_hash_message`. + + Several other message standards are proposed, but none have a clear + consensus. You'll need to manually comply with any of those message standards manually. + + :param message_hash: the 32-byte message hash to be signed + :type message_hash: hex str, bytes or int + :param private_key: the key to sign the message with + :type private_key: hex str, bytes, int or :class:`platon_keys.datatypes.PrivateKey` + :returns: Various details about the signature - most + importantly the fields: v, r, and s + :rtype: ~platon_account.datastructures.AttributeDict + + .. code-block:: python + + >>> msg = "I♥SF" + >>> from client_sdk_python.packages.platon_account.messages import defunct_hash_message + >>> msghash = defunct_hash_message(text=msg) + HexBytes('0x1476abb745d423bf09273f1afd887d951181d25adc66c4834a70491911b7f750') + >>> key = "0xb25c7db31feed9122727bf0939dc769a96564b2de4c4726d035b36ecf1e5b364" + >>> Account.signHash(msghash, key) + {'messageHash': HexBytes('0x1476abb745d423bf09273f1afd887d951181d25adc66c4834a70491911b7f750'), # noqa: E501 + 'r': 104389933075820307925104709181714897380569894203213074526835978196648170704563, + 's': 28205917190874851400050446352651915501321657673772411533993420917949420456142, + 'signature': HexBytes('0xe6ca9bba58c88611fad66a6ce8f996908195593807c4b38bd528d2cff09d4eb33e5bfbbf4d3e39b1a2fd816a7680c19ebebaf3a141b239934ad43cb33fcec8ce1c'), # noqa: E501 + 'v': 28} + + # these are equivalent: + >>> Account.signHash( + 0x1476abb745d423bf09273f1afd887d951181d25adc66c4834a70491911b7f750, + key + ) + >>> Account.signHash( + "0x1476abb745d423bf09273f1afd887d951181d25adc66c4834a70491911b7f750", + key + ) + ''' + msg_hash_bytes = HexBytes(message_hash) + if len(msg_hash_bytes) != 32: + raise ValueError("The message hash must be exactly 32-bytes") + + key = self._parsePrivateKey(private_key) + + (v, r, s, eth_signature_bytes) = sign_message_hash(key, msg_hash_bytes) + return AttributeDict({ + 'messageHash': msg_hash_bytes, + 'r': r, + 's': s, + 'v': v, + 'signature': HexBytes(eth_signature_bytes), + }) + + @combomethod + def signTransaction(self, transaction_dict, private_key, net_type=DEFAULTHRP): + ''' + Sign a transaction using a local private key. Produces signature details + and the hex-encoded transaction suitable for broadcast using + :meth:`w3.eth.sendRawTransaction() `. + + Create the transaction dict for a contract method with + `my_contract.functions.my_function().buildTransaction() + `_ + + :param dict transaction_dict: the transaction with keys: + nonce, chainId, to, data, value, gas, and gasPrice. + :param private_key: the private key to sign the data with + :type private_key: hex str, bytes, int or :class:`platon_keys.datatypes.PrivateKey` + :returns: Various details about the signature - most + importantly the fields: v, r, and s + :rtype: AttributeDict + + .. code-block:: python + + >>> transaction = { + # Note that the address must be in checksum format: + 'to': '0xF0109fC8DF283027b6285cc889F5aA624EaC1F55', + 'value': 1000000000, + 'gas': 2000000, + 'gasPrice': 234567897654321, + 'nonce': 0, + 'chainId': 1 + } + >>> key = '0x4c0883a69102937d6231471b5dbb6204fe5129617082792ae468d01a3f362318' + >>> signed = Account.signTransaction(transaction, key) + {'hash': HexBytes('0x6893a6ee8df79b0f5d64a180cd1ef35d030f3e296a5361cf04d02ce720d32ec5'), + 'r': 4487286261793418179817841024889747115779324305375823110249149479905075174044, + 'rawTransaction': HexBytes('0xf86a8086d55698372431831e848094f0109fc8df283027b6285cc889f5aa624eac1f55843b9aca008025a009ebb6ca057a0535d6186462bc0b465b561c94a295bdb0621fc19208ab149a9ca0440ffd775ce91a833ab410777204d5341a6f9fa91216a6f3ee2c051fea6a0428'), # noqa: E501 + 's': 30785525769477805655994251009256770582792548537338581640010273753578382951464, + 'v': 37} + >>> w3.eth.sendRawTransaction(signed.rawTransaction) + ''' + if not isinstance(transaction_dict, Mapping): + raise TypeError("transaction_dict must be dict-like, got %r" % transaction_dict) + + account = self.privateKeyToAccount(private_key, net_type) + + # allow from field, *only* if it matches the private key + if 'from' in transaction_dict: + if transaction_dict['from'] == account.address: + sanitized_transaction = dissoc(transaction_dict, 'from') + else: + raise TypeError("from field must match key's %s, but it was %s" % ( + account.address, + transaction_dict['from'], + )) + else: + sanitized_transaction = transaction_dict + + # sign transaction + ( + v, + r, + s, + rlp_encoded, + ) = sign_transaction_dict(account._key_obj, sanitized_transaction) + + transaction_hash = keccak(rlp_encoded) + + return AttributeDict({ + 'rawTransaction': HexBytes(rlp_encoded), + 'hash': HexBytes(transaction_hash), + 'r': r, + 's': s, + 'v': v, + }) + + @combomethod + def _parsePrivateKey(self, key): + ''' + Generate a :class:`platon_keys.datatypes.PrivateKey` from the provided key. If the + key is already of type :class:`platon_keys.datatypes.PrivateKey`, return the key. + + :param key: the private key from which a :class:`platon_keys.datatypes.PrivateKey` + will be generated + :type key: hex str, bytes, int or :class:`platon_keys.datatypes.PrivateKey` + :returns: the provided key represented as a :class:`platon_keys.datatypes.PrivateKey` + ''' + if isinstance(key, self._keys.PrivateKey): + return key + + try: + return self._keys.PrivateKey(HexBytes(key)) + except ValidationError as original_exception: + raise ValueError( + "The private key must be exactly 32 bytes long, instead of " + "%d bytes." % len(key) + ) from original_exception + + +if __name__ == '__main__': + account = Account().create(net_type=DEFAULTHRP) + print(account.address, account.privateKey) \ No newline at end of file diff --git a/client_sdk_python/packages/platon_account/datastructures.py b/client_sdk_python/packages/platon_account/datastructures.py new file mode 100644 index 0000000..81c18a7 --- /dev/null +++ b/client_sdk_python/packages/platon_account/datastructures.py @@ -0,0 +1,28 @@ +from attrdict import ( + AttrDict, +) + + +class AttributeDict(AttrDict): + ''' + See `AttrDict docs `_ + + This class differs only in that it is made immutable. This immutability + is **not** a security guarantee. It is only a style-check convenience. + ''' + def __setitem__(self, attr, val): + raise TypeError( + 'This data is immutable -- create a copy instead of modifying. ' + 'For example, AttributeDict(old, replace_key=replace_val).' + ) + + def _repr_pretty_(self, builder, cycle): + """ + Custom pretty output for the IPython console + """ + builder.text(self.__class__.__name__ + "(") + if cycle: + builder.text("") + else: + builder.pretty(dict(self)) + builder.text(")") diff --git a/client_sdk_python/packages/platon_account/internal/__init__.py b/client_sdk_python/packages/platon_account/internal/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/client_sdk_python/packages/platon_account/internal/signing.py b/client_sdk_python/packages/platon_account/internal/signing.py new file mode 100644 index 0000000..38c1a68 --- /dev/null +++ b/client_sdk_python/packages/platon_account/internal/signing.py @@ -0,0 +1,141 @@ +from cytoolz import ( + pipe, +) +from client_sdk_python.packages.eth_utils import ( + to_bytes, + to_int, +) + +from client_sdk_python.packages.platon_account.internal.transactions import ( + ChainAwareUnsignedTransaction, + UnsignedTransaction, + encode_transaction, + serializable_unsigned_transaction_from_dict, + strip_signature, +) + +CHAIN_ID_OFFSET = 35 +V_OFFSET = 27 + + +def sign_transaction_dict(eth_key, transaction_dict): + # generate RLP-serializable transaction, with defaults filled + unsigned_transaction = serializable_unsigned_transaction_from_dict(transaction_dict) + + transaction_hash = unsigned_transaction.hash() + + # detect chain + if isinstance(unsigned_transaction, UnsignedTransaction): + chain_id = None + else: + chain_id = unsigned_transaction.v + + # sign with private key + (v, r, s) = sign_transaction_hash(eth_key, transaction_hash, chain_id) + + # serialize transaction with rlp + encoded_transaction = encode_transaction(unsigned_transaction, vrs=(v, r, s)) + + return (v, r, s, encoded_transaction) + + +# watch here for updates to signature format: https://github.com/awake006/EIPs/issues/191 +def signature_wrapper(message, version=b'E'): + assert isinstance(message, bytes) + if version == b'E': + preamble = b'\x19awake006 Signed Message:\n' + size = str(len(message)).encode('utf-8') + return preamble + size + message + else: + raise NotImplementedError("Only the 'awake006 Signed Message' preamble is supported") + + +def hash_of_signed_transaction(txn_obj): + ''' + Regenerate the hash of the signed transaction object. + + 1. Infer the chain ID from the signature + 2. Strip out signature from transaction + 3. Annotate the transaction with that ID, if available + 4. Take the hash of the serialized, unsigned, chain-aware transaction + + Chain ID inference and annotation is according to EIP-155 + See details at https://github.com/awake006/EIPs/blob/master/EIPS/eip-155.md + + :return: the hash of the provided transaction, to be signed + ''' + (chain_id, _v) = extract_chain_id(txn_obj.v) + unsigned_parts = strip_signature(txn_obj) + if chain_id is None: + signable_transaction = UnsignedTransaction(*unsigned_parts) + else: + extended_transaction = unsigned_parts + [chain_id, 0, 0] + signable_transaction = ChainAwareUnsignedTransaction(*extended_transaction) + return signable_transaction.hash() + + +def extract_chain_id(raw_v): + ''' + Extracts chain ID, according to EIP-155 + @return (chain_id, v) + ''' + above_id_offset = raw_v - CHAIN_ID_OFFSET + if above_id_offset < 0: + if raw_v in {0, 1}: + return (None, raw_v + V_OFFSET) + elif raw_v in {27, 28}: + return (None, raw_v) + else: + raise ValueError("v %r is invalid, must be one of: 0, 1, 27, 28, 35+") + else: + (chain_id, v_bit) = divmod(above_id_offset, 2) + return (chain_id, v_bit + V_OFFSET) + + +def to_standard_signature_bytes(awake006_signature_bytes): + rs = awake006_signature_bytes[:-1] + v = to_int(awake006_signature_bytes[-1]) + standard_v = to_standard_v(v) + return rs + to_bytes(standard_v) + + +def to_standard_v(enhanced_v): + (_chain, chain_naive_v) = extract_chain_id(enhanced_v) + v_standard = chain_naive_v - V_OFFSET + assert v_standard in {0, 1} + return v_standard + + +def to_eth_v(v_raw, chain_id=None): + if chain_id is None: + v = v_raw + V_OFFSET + else: + v = v_raw + CHAIN_ID_OFFSET + 2 * chain_id + return v + + +def sign_transaction_hash(account, transaction_hash, chain_id): + signature = account.sign_msg_hash(transaction_hash) + (v_raw, r, s) = signature.vrs + v = to_eth_v(v_raw, chain_id) + return (v, r, s) + + +def _pad_to_eth_word(bytes_val): + return bytes_val.rjust(32, b'\0') + + +def to_bytes32(val): + return pipe( + val, + to_bytes, + _pad_to_eth_word, + ) + + +def sign_message_hash(key, msg_hash): + signature = key.sign_msg_hash(msg_hash) + (v_raw, r, s) = signature.vrs + v = to_eth_v(v_raw) + eth_signature_bytes = to_bytes32(r) + to_bytes32(s) + to_bytes(v) + return (v, r, s, eth_signature_bytes) diff --git a/client_sdk_python/packages/platon_account/internal/transactions.py b/client_sdk_python/packages/platon_account/internal/transactions.py new file mode 100644 index 0000000..279268c --- /dev/null +++ b/client_sdk_python/packages/platon_account/internal/transactions.py @@ -0,0 +1,205 @@ +import itertools + +from cytoolz import ( + curry, + dissoc, + identity, + merge, + partial, + pipe, +) +from eth_rlp import ( + HashableRLP, +) +from client_sdk_python.packages.eth_utils.curried import ( + apply_formatters_to_dict, + apply_one_of_formatters, + hexstr_if_str, + is_0x_prefixed, + is_bytes, + is_checksum_address, + is_integer, + is_string, + to_bytes, + to_int, +) +import rlp +from rlp.sedes import ( + big_endian_int, + binary, +) +from client_sdk_python.packages.platon_keys.utils.bech32 import decode + + +def bech32_address_bytes(val): + if not is_empty_or_checksum_address(val): + _, result = decode(val[0:3], val) + val = bytes(result) + return val + + +def modify_address(transaction_dict): + return dict(transaction_dict, to=bech32_address_bytes(transaction_dict.get("to"))) + + +def serializable_unsigned_transaction_from_dict(transaction_dict): + transaction_dict = modify_address(transaction_dict) + assert_valid_fields(transaction_dict) + filled_transaction = pipe( + transaction_dict, + dict, + partial(merge, TRANSACTION_DEFAULTS), + chain_id_to_v, + apply_formatters_to_dict(TRANSACTION_FORMATTERS), + ) + if 'v' in filled_transaction: + serializer = Transaction + else: + serializer = UnsignedTransaction + return serializer.from_dict(filled_transaction) + + +def encode_transaction(unsigned_transaction, vrs): + (v, r, s) = vrs + chain_naive_transaction = dissoc(unsigned_transaction.as_dict(), 'v', 'r', 's') + signed_transaction = Transaction(v=v, r=r, s=s, **chain_naive_transaction) + return rlp.encode(signed_transaction) + + +def is_int_or_prefixed_hexstr(val): + if is_integer(val): + return True + elif isinstance(val, str) and is_0x_prefixed(val): + return True + else: + return False + + +def is_empty_or_checksum_address(val): + if val in {None, b'', ''}: + return True + elif is_checksum_address(val): + return True + else: + return False + + +def is_empty_or_beach32_address(val): + # TODO: not implement + return True + + +def is_none(val): + return val is None + + +TRANSACTION_DEFAULTS = { + 'to': b'', + 'value': 0, + 'data': b'', + 'chainId': None, +} + +TRANSACTION_FORMATTERS = { + 'nonce': hexstr_if_str(to_int), + 'gasPrice': hexstr_if_str(to_int), + 'gas': hexstr_if_str(to_int), + 'to': apply_one_of_formatters(( + (is_string, hexstr_if_str(to_bytes)), + (is_bytes, identity), + (is_none, lambda val: b''), + )), + 'value': hexstr_if_str(to_int), + 'data': hexstr_if_str(to_bytes), + 'v': hexstr_if_str(to_int), + 'r': hexstr_if_str(to_int), + 's': hexstr_if_str(to_int), +} + +TRANSACTION_VALID_VALUES = { + 'nonce': is_int_or_prefixed_hexstr, + 'gasPrice': is_int_or_prefixed_hexstr, + 'gas': is_int_or_prefixed_hexstr, + 'to': is_empty_or_beach32_address, + 'value': is_int_or_prefixed_hexstr, + 'data': lambda val: isinstance(val, (int, str, bytes, bytearray)), + 'chainId': lambda val: val is None or is_int_or_prefixed_hexstr(val), +} + +ALLOWED_TRANSACTION_KEYS = { + 'nonce', + 'gasPrice', + 'gas', + 'to', + 'value', + 'data', + 'chainId', # set chainId to None if you want a transaction that can be replayed across networks +} + +REQUIRED_TRANSACITON_KEYS = ALLOWED_TRANSACTION_KEYS.difference(TRANSACTION_DEFAULTS.keys()) + + +def assert_valid_fields(transaction_dict): + # check if any keys are missing + missing_keys = REQUIRED_TRANSACITON_KEYS.difference(transaction_dict.keys()) + if missing_keys: + raise TypeError("Transaction must include these fields: %r" % missing_keys) + + # check if any extra keys were specified + superfluous_keys = set(transaction_dict.keys()).difference(ALLOWED_TRANSACTION_KEYS) + if superfluous_keys: + raise TypeError("Transaction must not include unrecognized fields: %r" % superfluous_keys) + + # check for valid types in each field + valid_fields = apply_formatters_to_dict(TRANSACTION_VALID_VALUES, transaction_dict) + if not all(valid_fields.values()): + invalid = {key: transaction_dict[key] for key, valid in valid_fields.items() if not valid} + raise TypeError("Transaction had invalid fields: %r" % invalid) + + +def chain_id_to_v(transaction_dict): + # See EIP 155 + chain_id = transaction_dict.pop('chainId') + if chain_id is None: + return transaction_dict + else: + return dict(transaction_dict, v=chain_id, r=0, s=0) + + +@curry +def fill_transaction_defaults(transaction): + return merge(TRANSACTION_DEFAULTS, transaction) + + +UNSIGNED_TRANSACTION_FIELDS = ( + ('nonce', big_endian_int), + ('gasPrice', big_endian_int), + ('gas', big_endian_int), + ('to', binary), + ('value', big_endian_int), + ('data', binary), +) + + +class Transaction(HashableRLP): + fields = UNSIGNED_TRANSACTION_FIELDS + ( + ('v', big_endian_int), + ('r', big_endian_int), + ('s', big_endian_int), + ) + + +class UnsignedTransaction(HashableRLP): + fields = UNSIGNED_TRANSACTION_FIELDS + + +ChainAwareUnsignedTransaction = Transaction + + +def strip_signature(txn): + unsigned_parts = itertools.islice(txn, len(UNSIGNED_TRANSACTION_FIELDS)) + return list(unsigned_parts) + + +def vrs_from(transaction): + return (getattr(transaction, part) for part in 'vrs') diff --git a/client_sdk_python/packages/platon_account/local.py b/client_sdk_python/packages/platon_account/local.py new file mode 100644 index 0000000..1492b80 --- /dev/null +++ b/client_sdk_python/packages/platon_account/local.py @@ -0,0 +1,4 @@ +# For backwards compatibility of explicit LocalAccount imports: +from client_sdk_python.packages.platon_account.signers.local import ( # noqa: F401 + LocalAccount, +) diff --git a/client_sdk_python/packages/platon_account/messages.py b/client_sdk_python/packages/platon_account/messages.py new file mode 100644 index 0000000..8f08daf --- /dev/null +++ b/client_sdk_python/packages/platon_account/messages.py @@ -0,0 +1,68 @@ +from cytoolz import ( + compose, +) +from client_sdk_python.packages.eth_utils import ( + keccak, + to_bytes, +) +from hexbytes import ( + HexBytes, +) + +from client_sdk_python.packages.platon_account.internal.signing import ( + signature_wrapper, +) + + +def defunct_hash_message(primitive=None, hexstr=None, text=None): + ''' + Convert the provided message into a message hash, to be signed. + This provides the same prefix and hashing approach as + :meth:`w3.eth.sign() `. That means that the + message will automatically be prepended with text + defined in EIP-191 as version 'E': ``b'\\x19awake006 Signed Message:\\n'`` + concatenated with the number of bytes in the message. + + Awkwardly, the number of bytes in the message is encoded in decimal ascii. So + if the message is 'abcde', then the length is encoded as the ascii + character '5'. This is one of the reasons that this message format is not preferred. + There is ambiguity when the message '00' is encoded, for example. + Only use this method if you must have compatibility with + :meth:`w3.eth.sign() `. + + Supply exactly one of the three arguments: + bytes, a hex string, or a unicode string. + + :param primitive: the binary message to be signed + :type primitive: bytes or int + :param str hexstr: the message encoded as hex + :param str text: the message as a series of unicode characters (a normal Py3 str) + :returns: The hash of the message, after adding the prefix + :rtype: ~hexbytes.main.HexBytes + + .. code-block:: python + + >>> from client_sdk_python.packages.platon_account.messages import defunct_hash_message + + >>> msg = "I♥SF" + >>> defunct_hash_message(text=msg) + HexBytes('0x1476abb745d423bf09273f1afd887d951181d25adc66c4834a70491911b7f750') + + # these four also produce the same hash: + >>> defunct_hash_message(w3.toBytes(text=msg)) + HexBytes('0x1476abb745d423bf09273f1afd887d951181d25adc66c4834a70491911b7f750') + + >>> defunct_hash_message(bytes(msg, encoding='utf-8')) + HexBytes('0x1476abb745d423bf09273f1afd887d951181d25adc66c4834a70491911b7f750') + + >>> Web3.toHex(text=msg) + '0x49e299a55346' + >>> defunct_hash_message(hexstr='0x49e299a55346') + HexBytes('0x1476abb745d423bf09273f1afd887d951181d25adc66c4834a70491911b7f750') + + >>> defunct_hash_message(0x49e299a55346) + HexBytes('0x1476abb745d423bf09273f1afd887d951181d25adc66c4834a70491911b7f750') + ''' + message_bytes = to_bytes(primitive, hexstr=hexstr, text=text) + recovery_hasher = compose(HexBytes, keccak, signature_wrapper) + return recovery_hasher(message_bytes) diff --git a/client_sdk_python/packages/platon_account/signers/__init__.py b/client_sdk_python/packages/platon_account/signers/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/client_sdk_python/packages/platon_account/signers/base.py b/client_sdk_python/packages/platon_account/signers/base.py new file mode 100644 index 0000000..1858066 --- /dev/null +++ b/client_sdk_python/packages/platon_account/signers/base.py @@ -0,0 +1,57 @@ +from abc import ( + ABC, + abstractmethod, +) + + +class BaseAccount(ABC): + ''' + Abstract class that defines a collection of convenience methods + to sign transactions and message hashes. + ''' + + @property + @abstractmethod + def address(self): + ''' + The checksummed public address for this account. + + .. code-block:: python + + >>> my_account.address + "0xF0109fC8DF283027b6285cc889F5aA624EaC1F55" + + ''' + pass + + @abstractmethod + def signHash(self, message_hash): + ''' + Sign the hash of a message, as in :meth:`~platon_account.account.Account.signHash` + but without specifying the private key. + + :var bytes message_hash: 32 byte hash of the message to sign + ''' + pass + + @abstractmethod + def signTransaction(self, transaction_dict): + ''' + Sign a transaction, as in :meth:`~platon_account.account.Account.signTransaction` + but without specifying the private key. + + :var dict transaction_dict: transaction with all fields specified + ''' + pass + + def __eq__(self, other): + ''' + Equality test between two accounts. + + Two accounts are considered the same if they are exactly the same type, + and can sign for the same address. + ''' + return type(self) == type(other) and self.address == other.address + + def __hash__(self): + return hash((type(self), self.address)) diff --git a/client_sdk_python/packages/platon_account/signers/local.py b/client_sdk_python/packages/platon_account/signers/local.py new file mode 100644 index 0000000..4396a32 --- /dev/null +++ b/client_sdk_python/packages/platon_account/signers/local.py @@ -0,0 +1,69 @@ +from client_sdk_python.packages.platon_account.signers.base import ( + BaseAccount, +) +from client_sdk_python.packages.platon_keys.utils.address import DEFAULTHRP + + +class LocalAccount(BaseAccount): + ''' + A collection of convenience methods to sign and encrypt, with an embedded private key. + + :var bytes privateKey: the 32-byte private key data + + .. code-block:: python + + >>> my_local_account.address + "0xF0109fC8DF283027b6285cc889F5aA624EaC1F55" + >>> my_local_account.privateKey + b"\\x01\\x23..." + + You can also get the private key by casting the account to :class:`bytes`: + + .. code-block:: python + + >>> bytes(my_local_account) + b"\\x01\\x23..." + ''' + + def __init__(self, key, account, net_type=DEFAULTHRP): + ''' + :param platon_keys.PrivateKey key: to prefill in private key execution + :param web3.account.Account account: the key-unaware management API + ''' + self._publicapi = account + self._address = key.public_key.to_bech32_address(net_type) + + key_raw = key.to_bytes() + self._privateKey = key_raw + + self._key_obj = key + + @property + def address(self): + return self._address + + @property + def privateKey(self): + ''' + Get the private key. + ''' + return self._privateKey + + def encrypt(self, password): + ''' + Generate a string with the encrypted key, as in + :meth:`~platon_account.account.Account.encrypt`, but without a private key argument. + ''' + return self._publicapi.encrypt(self.privateKey, password) + + def signHash(self, message_hash): + return self._publicapi.signHash( + message_hash, + private_key=self.privateKey, + ) + + def signTransaction(self, transaction_dict): + return self._publicapi.signTransaction(transaction_dict, self.privateKey) + + def __bytes__(self): + return self.privateKey diff --git a/client_sdk_python/packages/platon_keyfile/__init__.py b/client_sdk_python/packages/platon_keyfile/__init__.py new file mode 100644 index 0000000..9b5a0a6 --- /dev/null +++ b/client_sdk_python/packages/platon_keyfile/__init__.py @@ -0,0 +1,20 @@ +from __future__ import absolute_import + +import pkg_resources +import warnings +import sys + +from client_sdk_python.packages.platon_keyfile.keyfile import ( # noqa: F401 + load_keyfile, + create_keyfile_json, + decode_keyfile_json, + extract_key_from_keyfile, +) + + +if sys.version_info.major < 3: + warnings.simplefilter('always', DeprecationWarning) + warnings.warn(DeprecationWarning( + "The `platon-keyfile` library is dropping support for Python 2. Upgrade to Python 3." + )) + warnings.resetwarnings() diff --git a/client_sdk_python/packages/platon_keyfile/keyfile.py b/client_sdk_python/packages/platon_keyfile/keyfile.py new file mode 100644 index 0000000..dcb6c68 --- /dev/null +++ b/client_sdk_python/packages/platon_keyfile/keyfile.py @@ -0,0 +1,278 @@ +import hashlib +import hmac +import json +import uuid + +from Crypto import Random +from Crypto.Cipher import AES +from Crypto.Protocol.KDF import scrypt +from Crypto.Util import Counter + +from client_sdk_python.packages.platon_keys import keys + +from client_sdk_python.packages.eth_utils import ( + big_endian_to_int, + decode_hex, + encode_hex, + int_to_big_endian, + is_dict, + is_string, + keccak, + remove_0x_prefix, + to_dict, +) + + +def encode_hex_no_prefix(value): + return remove_0x_prefix(encode_hex(value)) + + +def load_keyfile(path_or_file_obj): + if is_string(path_or_file_obj): + with open(path_or_file_obj) as keyfile_file: + return json.load(keyfile_file) + else: + return json.load(path_or_file_obj) + + +def create_keyfile_json(hrp,private_key, password, version=3, kdf="scrypt", + iterations=None, salt_size=16): + if version == 3: + return _create_v3_keyfile_json( + hrp, + private_key, + password, + kdf, + iterations, + salt_size) + else: + raise NotImplementedError("Not yet implemented") + + +def decode_keyfile_json(raw_keyfile_json, password): + keyfile_json = normalize_keys(raw_keyfile_json) + version = keyfile_json['version'] + + if version == 3: + return _decode_keyfile_json_v3(keyfile_json, password) + else: + raise NotImplementedError("Not yet implemented") + + +def extract_key_from_keyfile(path_or_file_obj, password): + keyfile_json = load_keyfile(path_or_file_obj) + private_key = decode_keyfile_json(keyfile_json, password) + return private_key + + +@to_dict +def normalize_keys(keyfile_json): + for key, value in keyfile_json.items(): + if is_string(key): + norm_key = key.lower() + else: + norm_key = key + + if is_dict(value): + norm_value = normalize_keys(value) + else: + norm_value = value + + yield norm_key, norm_value + + +# +# Version 3 creators +# +DKLEN = 32 +SCRYPT_R = 1 +SCRYPT_P = 8 + + +def _create_v3_keyfile_json(hrp,private_key, password, kdf, + work_factor=None, salt_size=16): + salt = Random.get_random_bytes(salt_size) + + if work_factor is None: + work_factor = get_default_work_factor_for_kdf(kdf) + + if kdf == 'pbkdf2': + derived_key = _pbkdf2_hash( + password, + hash_name='sha256', + salt=salt, + iterations=work_factor, + dklen=DKLEN, + ) + kdfparams = { + 'c': work_factor, + 'dklen': DKLEN, + 'prf': 'hmac-sha256', + 'salt': encode_hex_no_prefix(salt), + } + elif kdf == 'scrypt': + derived_key = _scrypt_hash( + password, + salt=salt, + buflen=DKLEN, + r=SCRYPT_R, + p=SCRYPT_P, + n=work_factor, + ) + kdfparams = { + 'dklen': DKLEN, + 'n': work_factor, + 'r': SCRYPT_R, + 'p': SCRYPT_P, + 'salt': encode_hex_no_prefix(salt), + } + else: + raise NotImplementedError("KDF not implemented: {0}".format(kdf)) + + iv = big_endian_to_int(Random.get_random_bytes(16)) + encrypt_key = derived_key[:16] + ciphertext = encrypt_aes_ctr(private_key, encrypt_key, iv) + mac = keccak(derived_key[16:32] + ciphertext) + pub = keys.PrivateKey(private_key).public_key + return { + 'address': pub.to_bech32_address(hrp), + 'crypto': { + 'cipher': 'aes-128-ctr', + 'cipherparams': { + 'iv': encode_hex_no_prefix(int_to_big_endian(iv)), + }, + 'ciphertext': encode_hex_no_prefix(ciphertext), + 'kdf': kdf, + 'kdfparams': kdfparams, + 'mac': encode_hex_no_prefix(mac), + }, + 'id': str(uuid.uuid4()), + 'version': 3, + } + + +# +# Verson 3 decoder +# +def _decode_keyfile_json_v3(keyfile_json, password): + crypto = keyfile_json['crypto'] + kdf = crypto['kdf'] + + # Derive the encryption key from the password using the key derivation + # function. + if kdf == 'pbkdf2': + derived_key = _derive_pbkdf_key(crypto, password) + elif kdf == 'scrypt': + derived_key = _derive_scrypt_key(crypto, password) + else: + raise TypeError("Unsupported key derivation function: {0}".format(kdf)) + + # Validate that the derived key matchs the provided MAC + ciphertext = decode_hex(crypto['ciphertext']) + mac = keccak(derived_key[16:32] + ciphertext) + + expected_mac = decode_hex(crypto['mac']) + + if not hmac.compare_digest(mac, expected_mac): + raise ValueError("MAC mismatch") + + # Decrypt the ciphertext using the derived encryption key to get the + # private key. + encrypt_key = derived_key[:16] + cipherparams = crypto['cipherparams'] + iv = big_endian_to_int(decode_hex(cipherparams['iv'])) + + private_key = decrypt_aes_ctr(ciphertext, encrypt_key, iv) + + return private_key + + +# +# Key derivation +# +def _derive_pbkdf_key(crypto, password): + kdf_params = crypto['kdfparams'] + salt = decode_hex(kdf_params['salt']) + dklen = kdf_params['dklen'] + should_be_hmac, _, hash_name = kdf_params['prf'].partition('-') + assert should_be_hmac == 'hmac' + iterations = kdf_params['c'] + + derive_pbkdf_key = _pbkdf2_hash(password, hash_name, salt, iterations, dklen) + + return derive_pbkdf_key + + +def _derive_scrypt_key(crypto, password): + kdf_params = crypto['kdfparams'] + salt = decode_hex(kdf_params['salt']) + p = kdf_params['p'] + r = kdf_params['r'] + n = kdf_params['n'] + buflen = kdf_params['dklen'] + + derived_scrypt_key = _scrypt_hash( + password, + salt=salt, + n=n, + r=r, + p=p, + buflen=buflen, + ) + return derived_scrypt_key + + +def _scrypt_hash(password, salt, n, r, p, buflen): + derived_key = scrypt( + password, + salt=salt, + key_len=buflen, + N=n, + r=r, + p=p, + num_keys=1, + ) + return derived_key + + +def _pbkdf2_hash(password, hash_name, salt, iterations, dklen): + derived_key = hashlib.pbkdf2_hmac( + hash_name=hash_name, + password=password, + salt=salt, + iterations=iterations, + dklen=dklen, + ) + + return derived_key + + +# +# Encryption and Decryption +# +def decrypt_aes_ctr(ciphertext, key, iv): + ctr = Counter.new(128, initial_value=iv, allow_wraparound=True) + encryptor = AES.new(key, AES.MODE_CTR, counter=ctr) + return encryptor.decrypt(ciphertext) + + +def encrypt_aes_ctr(value, key, iv): + ctr = Counter.new(128, initial_value=iv, allow_wraparound=True) + encryptor = AES.new(key, AES.MODE_CTR, counter=ctr) + ciphertext = encryptor.encrypt(value) + return ciphertext + + +# +# Utility +# +def get_default_work_factor_for_kdf(kdf): + if kdf == 'pbkdf2': + return 1000000 + elif kdf == 'scrypt': + return 262144 + else: + raise ValueError("Unsupported key derivation function: {0}".format(kdf)) + +if __name__ == '__main__': + print(create_keyfile_json('atp',bytes.fromhex("deb2bd10eedef6d89cd8fac224dc8f1bdd26ed1c4b5c513995efb1b33404db17"),"88888888")) \ No newline at end of file diff --git a/client_sdk_python/packages/platon_keys/__init__.py b/client_sdk_python/packages/platon_keys/__init__.py new file mode 100644 index 0000000..4e156ff --- /dev/null +++ b/client_sdk_python/packages/platon_keys/__init__.py @@ -0,0 +1,18 @@ +from __future__ import absolute_import + +import sys +import warnings + + +if sys.version_info.major < 3: + warnings.simplefilter('always', DeprecationWarning) + warnings.warn(DeprecationWarning( + "The `platon-keys` library is dropping support for Python 2. Upgrade to Python 3." + )) + warnings.resetwarnings() + + +from .main import ( # noqa: F401 + KeyAPI, + lazy_key_api as keys, +) diff --git a/client_sdk_python/packages/platon_keys/backends/__init__.py b/client_sdk_python/packages/platon_keys/backends/__init__.py new file mode 100644 index 0000000..21899de --- /dev/null +++ b/client_sdk_python/packages/platon_keys/backends/__init__.py @@ -0,0 +1,36 @@ +from __future__ import absolute_import + +import os +from typing import Type + +from client_sdk_python.packages.platon_keys.utils.module_loading import ( + import_string, +) + +from .base import BaseECCBackend # noqa: F401 +from .coincurve import ( # noqa: F401 + CoinCurveECCBackend, + is_coincurve_available, +) +from .native import NativeECCBackend # noqa: F401 + + +def get_default_backend_class() -> str: + if is_coincurve_available(): + return 'client_sdk_python.packages.platon_keys.backends.CoinCurveECCBackend' + else: + return 'client_sdk_python.packages.platon_keys.backends.NativeECCBackend' + + +def get_backend_class(import_path: str = None) -> Type[BaseECCBackend]: + if import_path is None: + import_path = os.environ.get( + 'ECC_BACKEND_CLASS', + get_default_backend_class(), + ) + return import_string(import_path) + + +def get_backend(import_path: str = None) -> BaseECCBackend: + backend_class = get_backend_class(import_path) + return backend_class() diff --git a/client_sdk_python/packages/platon_keys/backends/base.py b/client_sdk_python/packages/platon_keys/backends/base.py new file mode 100644 index 0000000..6f9a6ff --- /dev/null +++ b/client_sdk_python/packages/platon_keys/backends/base.py @@ -0,0 +1,44 @@ +from typing import Any # noqa: F401 + +from client_sdk_python.packages.platon_keys.datatypes import ( + BaseSignature, + NonRecoverableSignature, + PrivateKey, + PublicKey, + Signature, +) + + +class BaseECCBackend(object): + def ecdsa_sign(self, + msg_hash: bytes, + private_key: PrivateKey) -> Signature: + raise NotImplementedError() + + def ecdsa_sign_non_recoverable(self, + msg_hash: bytes, + private_key: PrivateKey) -> NonRecoverableSignature: + raise NotImplementedError() + + def ecdsa_verify(self, + msg_hash: bytes, + signature: BaseSignature, + public_key: PublicKey) -> bool: + raise NotImplementedError() + + def ecdsa_recover(self, + msg_hash: bytes, + signature: Signature) -> PublicKey: + raise NotImplementedError() + + def private_key_to_public_key(self, + private_key: PrivateKey) -> PublicKey: + raise NotImplementedError() + + def decompress_public_key_bytes(self, + compressed_public_key_bytes: bytes) -> bytes: + raise NotImplementedError() + + def compress_public_key_bytes(self, + uncompressed_public_key_bytes: bytes) -> bytes: + raise NotImplementedError() diff --git a/client_sdk_python/packages/platon_keys/backends/coincurve.py b/client_sdk_python/packages/platon_keys/backends/coincurve.py new file mode 100644 index 0000000..3b0fdb4 --- /dev/null +++ b/client_sdk_python/packages/platon_keys/backends/coincurve.py @@ -0,0 +1,127 @@ +from __future__ import absolute_import + +from typing import Optional # noqa: F401 + +from client_sdk_python.packages.eth_utils import ( + big_endian_to_int, +) + +from client_sdk_python.packages.platon_keys.datatypes import ( # noqa: F401 + BaseSignature, + NonRecoverableSignature, + PrivateKey, + PublicKey, + Signature, +) +from client_sdk_python.packages.platon_keys.exceptions import ( + BadSignature, +) +from client_sdk_python.packages.platon_keys.validation import ( + validate_uncompressed_public_key_bytes, +) +from client_sdk_python.packages.platon_keys.utils import ( + der, +) +from client_sdk_python.packages.platon_keys.utils.numeric import ( + coerce_low_s, +) + +from .base import BaseECCBackend + + +def is_coincurve_available() -> bool: + try: + import coincurve # noqa: F401 + except ImportError: + return False + else: + return True + + +class CoinCurveECCBackend(BaseECCBackend): + def __init__(self) -> None: + try: + import coincurve + except ImportError: + raise ImportError("The CoinCurveECCBackend requires the coincurve \ + library which is not available for import.") + self.keys = coincurve.keys + self.ecdsa = coincurve.ecdsa + super(CoinCurveECCBackend, self).__init__() + + def ecdsa_sign(self, + msg_hash: bytes, + private_key: PrivateKey) -> Signature: + private_key_bytes = private_key.to_bytes() + signature_bytes = self.keys.PrivateKey(private_key_bytes).sign_recoverable( + msg_hash, + hasher=None, + ) + signature = Signature(signature_bytes, backend=self) + return signature + + def ecdsa_sign_non_recoverable(self, + msg_hash: bytes, + private_key: PrivateKey) -> NonRecoverableSignature: + private_key_bytes = private_key.to_bytes() + + der_encoded_signature = self.keys.PrivateKey(private_key_bytes).sign( + msg_hash, + hasher=None, + ) + rs = der.two_int_sequence_decoder(der_encoded_signature) + + signature = NonRecoverableSignature(rs=rs, backend=self) + return signature + + def ecdsa_verify(self, + msg_hash: bytes, + signature: BaseSignature, + public_key: PublicKey) -> bool: + # coincurve rejects signatures with a high s, so convert to the equivalent low s form + low_s = coerce_low_s(signature.s) + der_encoded_signature = der.two_int_sequence_encoder(signature.r, low_s) + coincurve_public_key = self.keys.PublicKey(b"\x04" + public_key.to_bytes()) + return coincurve_public_key.verify( + der_encoded_signature, + msg_hash, + hasher=None, + ) + + def ecdsa_recover(self, + msg_hash: bytes, + signature: Signature) -> PublicKey: + signature_bytes = signature.to_bytes() + try: + public_key_bytes = self.keys.PublicKey.from_signature_and_message( + signature_bytes, + msg_hash, + hasher=None, + ).format(compressed=False)[1:] + except (ValueError, Exception) as err: + # `coincurve` can raise `ValueError` or `Exception` dependending on + # how the signature is invalid. + raise BadSignature(str(err)) + public_key = PublicKey(public_key_bytes, backend=self) + return public_key + + def private_key_to_public_key(self, private_key: PrivateKey) -> PublicKey: + public_key_bytes = self.keys.PrivateKey(private_key.to_bytes()).public_key.format( + compressed=False, + )[1:] + return PublicKey(public_key_bytes, backend=self) + + def decompress_public_key_bytes(self, + compressed_public_key_bytes: bytes) -> bytes: + public_key = self.keys.PublicKey(compressed_public_key_bytes) + return public_key.format(compressed=False)[1:] + + def compress_public_key_bytes(self, + uncompressed_public_key_bytes: bytes) -> bytes: + validate_uncompressed_public_key_bytes(uncompressed_public_key_bytes) + point = ( + big_endian_to_int(uncompressed_public_key_bytes[:32]), + big_endian_to_int(uncompressed_public_key_bytes[32:]), + ) + public_key = self.keys.PublicKey.from_point(*point) + return public_key.format(compressed=True) diff --git a/client_sdk_python/packages/platon_keys/backends/native/__init__.py b/client_sdk_python/packages/platon_keys/backends/native/__init__.py new file mode 100644 index 0000000..d7a2a73 --- /dev/null +++ b/client_sdk_python/packages/platon_keys/backends/native/__init__.py @@ -0,0 +1,5 @@ +from __future__ import absolute_import + +from .main import ( # noqa: F401 + NativeECCBackend, +) diff --git a/client_sdk_python/packages/platon_keys/backends/native/ecdsa.py b/client_sdk_python/packages/platon_keys/backends/native/ecdsa.py new file mode 100644 index 0000000..2c6c9cf --- /dev/null +++ b/client_sdk_python/packages/platon_keys/backends/native/ecdsa.py @@ -0,0 +1,164 @@ +""" +Functions lifted from https://github.com/vbuterin/pybitcointools +""" +import hashlib +import hmac +from typing import (Any, Callable, Optional, Tuple) # noqa: F401 + +from client_sdk_python.packages.eth_utils import ( + int_to_big_endian, + big_endian_to_int, +) + +from client_sdk_python.packages.platon_keys.constants import ( + SECPK1_N as N, + SECPK1_G as G, + SECPK1_Gx as Gx, + SECPK1_Gy as Gy, + SECPK1_P as P, + SECPK1_A as A, + SECPK1_B as B, +) +from client_sdk_python.packages.platon_keys.exceptions import ( + BadSignature, +) + +from client_sdk_python.packages.platon_keys.utils.padding import pad32 + +from .jacobian import ( + inv, + fast_multiply, + fast_add, + jacobian_add, + jacobian_multiply, + from_jacobian, +) + + +def decode_public_key(public_key_bytes: bytes) -> Tuple[int, int]: + left = big_endian_to_int(public_key_bytes[0:32]) + right = big_endian_to_int(public_key_bytes[32:64]) + return left, right + + +def encode_raw_public_key(raw_public_key: Tuple[int, int]) -> bytes: + left, right = raw_public_key + return b''.join(( + pad32(int_to_big_endian(left)), + pad32(int_to_big_endian(right)), + )) + + +def private_key_to_public_key(private_key_bytes: bytes) -> bytes: + private_key_as_num = big_endian_to_int(private_key_bytes) + + if private_key_as_num >= N: + raise Exception("Invalid privkey") + + raw_public_key = fast_multiply(G, private_key_as_num) + public_key_bytes = encode_raw_public_key(raw_public_key) + return public_key_bytes + + +def compress_public_key(uncompressed_public_key_bytes: bytes) -> bytes: + x, y = decode_public_key(uncompressed_public_key_bytes) + if y % 2 == 0: + prefix = b"\x02" + else: + prefix = b"\x03" + return prefix + pad32(int_to_big_endian(x)) + + +def decompress_public_key(compressed_public_key_bytes: bytes) -> bytes: + if len(compressed_public_key_bytes) != 33: + raise ValueError("Invalid compressed public key") + + prefix = compressed_public_key_bytes[0] + if prefix not in (2, 3): + raise ValueError("Invalid compressed public key") + + x = big_endian_to_int(compressed_public_key_bytes[1:]) + y_squared = (x**3 + A * x + B) % P + y_abs = pow(y_squared, ((P + 1) // 4), P) + + if (prefix == 2 and y_abs & 1 == 1) or (prefix == 3 and y_abs & 1 == 0): + y = (-y_abs) % P + else: + y = y_abs + + return encode_raw_public_key((x, y)) + + +def deterministic_generate_k(msg_hash: bytes, + private_key_bytes: bytes, + digest_fn: Callable[[], Any] = hashlib.sha256) -> int: + v_0 = b'\x01' * 32 + k_0 = b'\x00' * 32 + + k_1 = hmac.new(k_0, v_0 + b'\x00' + private_key_bytes + msg_hash, digest_fn).digest() + v_1 = hmac.new(k_1, v_0, digest_fn).digest() + k_2 = hmac.new(k_1, v_1 + b'\x01' + private_key_bytes + msg_hash, digest_fn).digest() + v_2 = hmac.new(k_2, v_1, digest_fn).digest() + + kb = hmac.new(k_2, v_2, digest_fn).digest() + k = big_endian_to_int(kb) + return k + + +def ecdsa_raw_sign(msg_hash: bytes, + private_key_bytes: bytes) -> Tuple[int, int, int]: + z = big_endian_to_int(msg_hash) + k = deterministic_generate_k(msg_hash, private_key_bytes) + + r, y = fast_multiply(G, k) + s_raw = inv(k, N) * (z + r * big_endian_to_int(private_key_bytes)) % N + + v = 27 + ((y % 2) ^ (0 if s_raw * 2 < N else 1)) + s = s_raw if s_raw * 2 < N else N - s_raw + + return v - 27, r, s + + +def ecdsa_raw_verify(msg_hash: bytes, + rs: Tuple[int, int], + public_key_bytes: bytes) -> bool: + raw_public_key = decode_public_key(public_key_bytes) + + r, s = rs + + w = inv(s, N) + z = big_endian_to_int(msg_hash) + + u1, u2 = z * w % N, r * w % N + x, y = fast_add( + fast_multiply(G, u1), + fast_multiply(raw_public_key, u2), + ) + return bool(r == x and (r % N) and (s % N)) + + +def ecdsa_raw_recover(msg_hash: bytes, + vrs: Tuple[int, int, int]) -> bytes: + v, r, s = vrs + v += 27 + + if not (27 <= v <= 34): + raise BadSignature("%d must in range 27-31" % v) + + x = r + + xcubedaxb = (x * x * x + A * x + B) % P + beta = pow(xcubedaxb, (P + 1) // 4, P) + y = beta if v % 2 ^ beta % 2 else (P - beta) + # If xcubedaxb is not a quadratic residue, then r cannot be the x coord + # for a point on the curve, and so the sig is invalid + if (xcubedaxb - y * y) % P != 0 or not (r % N) or not (s % N): + raise BadSignature("Invalid signature") + z = big_endian_to_int(msg_hash) + Gz = jacobian_multiply((Gx, Gy, 1), (N - z) % N) + XY = jacobian_multiply((x, y, 1), s) + Qr = jacobian_add(Gz, XY) + Q = jacobian_multiply(Qr, inv(r, N)) + raw_public_key = from_jacobian(Q) + + return encode_raw_public_key(raw_public_key) diff --git a/client_sdk_python/packages/platon_keys/backends/native/jacobian.py b/client_sdk_python/packages/platon_keys/backends/native/jacobian.py new file mode 100644 index 0000000..9128cf6 --- /dev/null +++ b/client_sdk_python/packages/platon_keys/backends/native/jacobian.py @@ -0,0 +1,92 @@ +from typing import Tuple # noqa: F401 + +from client_sdk_python.packages.platon_keys.constants import ( + SECPK1_P as P, + SECPK1_N as N, + SECPK1_A as A, +) + + +def inv(a: int, n: int) -> int: + if a == 0: + return 0 + lm, hm = 1, 0 + low, high = a % n, n + while low > 1: + r = high // low + nm, new = hm - lm * r, high - low * r + lm, low, hm, high = nm, new, lm, low + return lm % n + + +def to_jacobian(p: Tuple[int, int]) -> Tuple[int, int, int]: + o = (p[0], p[1], 1) + return o + + +def jacobian_double(p: Tuple[int, int, int]) -> Tuple[int, int, int]: + if not p[1]: + return (0, 0, 0) + ysq = (p[1] ** 2) % P + S = (4 * p[0] * ysq) % P + M = (3 * p[0] ** 2 + A * p[2] ** 4) % P + nx = (M**2 - 2 * S) % P + ny = (M * (S - nx) - 8 * ysq ** 2) % P + nz = (2 * p[1] * p[2]) % P + return (nx, ny, nz) + + +def jacobian_add(p: Tuple[int, int, int], + q: Tuple[int, int, int]) -> Tuple[int, int, int]: + if not p[1]: + return q + if not q[1]: + return p + U1 = (p[0] * q[2] ** 2) % P + U2 = (q[0] * p[2] ** 2) % P + S1 = (p[1] * q[2] ** 3) % P + S2 = (q[1] * p[2] ** 3) % P + if U1 == U2: + if S1 != S2: + return (0, 0, 1) + return jacobian_double(p) + H = U2 - U1 + R = S2 - S1 + H2 = (H * H) % P + H3 = (H * H2) % P + U1H2 = (U1 * H2) % P + nx = (R ** 2 - H3 - 2 * U1H2) % P + ny = (R * (U1H2 - nx) - S1 * H3) % P + nz = (H * p[2] * q[2]) % P + return (nx, ny, nz) + + +def from_jacobian(p: Tuple[int, int, int]) -> Tuple[int, int]: + z = inv(p[2], P) + return ((p[0] * z**2) % P, (p[1] * z**3) % P) + + +def jacobian_multiply(a: Tuple[int, int, int], + n: int) -> Tuple[int, int, int]: + if a[1] == 0 or n == 0: + return (0, 0, 1) + if n == 1: + return a + if n < 0 or n >= N: + return jacobian_multiply(a, n % N) + if (n % 2) == 0: + return jacobian_double(jacobian_multiply(a, n // 2)) + elif (n % 2) == 1: + return jacobian_add(jacobian_double(jacobian_multiply(a, n // 2)), a) + else: + raise Exception("Invariant: Unreachable code path") + + +def fast_multiply(a: Tuple[int, int], + n: int) -> Tuple[int, int]: + return from_jacobian(jacobian_multiply(to_jacobian(a), n)) + + +def fast_add(a: Tuple[int, int], + b: Tuple[int, int]) -> Tuple[int, int]: + return from_jacobian(jacobian_add(to_jacobian(a), to_jacobian(b))) diff --git a/client_sdk_python/packages/platon_keys/backends/native/main.py b/client_sdk_python/packages/platon_keys/backends/native/main.py new file mode 100644 index 0000000..c4f6cb0 --- /dev/null +++ b/client_sdk_python/packages/platon_keys/backends/native/main.py @@ -0,0 +1,63 @@ +from __future__ import absolute_import + +from typing import Optional # noqa: F401 + +from .ecdsa import ( + ecdsa_raw_recover, + ecdsa_raw_sign, + ecdsa_raw_verify, + private_key_to_public_key, + compress_public_key, + decompress_public_key, +) + +from client_sdk_python.packages.platon_keys.backends.base import BaseECCBackend +from client_sdk_python.packages.platon_keys.datatypes import ( # noqa: F401 + BaseSignature, + NonRecoverableSignature, + PrivateKey, + PublicKey, + Signature, +) + + +class NativeECCBackend(BaseECCBackend): + def ecdsa_sign(self, + msg_hash: bytes, + private_key: PrivateKey) -> Signature: + signature_vrs = ecdsa_raw_sign(msg_hash, private_key.to_bytes()) + signature = Signature(vrs=signature_vrs, backend=self) + return signature + + def ecdsa_sign_non_recoverable(self, + msg_hash: bytes, + private_key: PrivateKey) -> NonRecoverableSignature: + _, signature_r, signature_s = ecdsa_raw_sign(msg_hash, private_key.to_bytes()) + signature = NonRecoverableSignature(rs=(signature_r, signature_s), backend=self) + return signature + + def ecdsa_verify(self, + msg_hash: bytes, + signature: BaseSignature, + public_key: PublicKey) -> bool: + return ecdsa_raw_verify(msg_hash, signature.rs, public_key.to_bytes()) + + def ecdsa_recover(self, + msg_hash: bytes, + signature: Signature) -> PublicKey: + public_key_bytes = ecdsa_raw_recover(msg_hash, signature.vrs) + public_key = PublicKey(public_key_bytes, backend=self) + return public_key + + def private_key_to_public_key(self, private_key: PrivateKey) -> PublicKey: + public_key_bytes = private_key_to_public_key(private_key.to_bytes()) + public_key = PublicKey(public_key_bytes, backend=self) + return public_key + + def decompress_public_key_bytes(self, + compressed_public_key_bytes: bytes) -> bytes: + return decompress_public_key(compressed_public_key_bytes) + + def compress_public_key_bytes(self, + uncompressed_public_key_bytes: bytes) -> bytes: + return compress_public_key(uncompressed_public_key_bytes) diff --git a/client_sdk_python/packages/platon_keys/constants.py b/client_sdk_python/packages/platon_keys/constants.py new file mode 100644 index 0000000..1ca95bc --- /dev/null +++ b/client_sdk_python/packages/platon_keys/constants.py @@ -0,0 +1,13 @@ +from typing import Tuple # noqa: F401 + + +# +# SECPK1N +# +SECPK1_P = 2**256 - 2**32 - 977 # type: int +SECPK1_N = 115792089237316195423570985008687907852837564279074904382605163141518161494337 # type: int # noqa: E501 +SECPK1_A = 0 # type: int # noqa: E501 +SECPK1_B = 7 # type: int # noqa: E501 +SECPK1_Gx = 55066263022277343669578718895168534326250603453777594175500187360389116729240 # type: int # noqa: E501 +SECPK1_Gy = 32670510020758816978083085130507043184471273380659243275938904335757337482424 # type: int # noqa: E501 +SECPK1_G = (SECPK1_Gx, SECPK1_Gy) # type: Tuple[int, int] diff --git a/client_sdk_python/packages/platon_keys/datatypes.py b/client_sdk_python/packages/platon_keys/datatypes.py new file mode 100644 index 0000000..074b559 --- /dev/null +++ b/client_sdk_python/packages/platon_keys/datatypes.py @@ -0,0 +1,456 @@ +from __future__ import absolute_import + +from abc import ( + ABC, + abstractmethod, +) +import codecs +import collections.abc +import sys +from typing import ( # noqa: F401 + Any, + Tuple, + Union, + Type, + TYPE_CHECKING, +) + +from client_sdk_python.packages.eth_utils import ( + big_endian_to_int, + encode_hex, + int_to_big_endian, + is_bytes, + is_string, + keccak, + to_checksum_address, + to_normalized_address, +) +from client_sdk_python.packages.eth_utils.typing import ( + ChecksumAddress, +) + +from client_sdk_python.packages.platon_keys.utils.address import ( + public_key_bytes_to_address, address_bytes_to_address, address_bytes_to_bech32_address +) +from client_sdk_python.packages.platon_keys.utils.numeric import ( + int_to_byte, +) +from client_sdk_python.packages.platon_keys.utils.padding import ( + pad32, +) + +from client_sdk_python.packages.platon_keys.exceptions import ( + BadSignature, + ValidationError, +) +from client_sdk_python.packages.platon_keys.validation import ( + validate_private_key_bytes, + validate_compressed_public_key_bytes, + validate_uncompressed_public_key_bytes, + validate_recoverable_signature_bytes, + validate_non_recoverable_signature_bytes, + validate_signature_v, + validate_signature_r_or_s, +) + +if TYPE_CHECKING: + from client_sdk_python.packages.platon_keys.backends.base import BaseECCBackend # noqa: F401 + + +# Must compare against version_info[0] and not version_info.major to please mypy. +if sys.version_info[0] == 2: + ByteString = type( + b'BaseString', + (collections.abc.Sequence, basestring), # noqa: F821 + {}, + ) # type: Any +else: + ByteString = collections.abc.ByteString + + +class LazyBackend: + def __init__(self, + backend: 'Union[BaseECCBackend, Type[BaseECCBackend], str, None]' = None, + ) -> None: + from client_sdk_python.packages.platon_keys.backends.base import ( # noqa: F811 + BaseECCBackend, + ) + + if backend is None: + pass + elif isinstance(backend, BaseECCBackend): + pass + elif isinstance(backend, type) and issubclass(backend, BaseECCBackend): + backend = backend() + elif is_string(backend): + backend = self.get_backend(backend) + else: + raise ValueError( + "Unsupported format for ECC backend. Must be an instance or " + "subclass of `platon_keys.backends.BaseECCBackend` or a string of " + "the dot-separated import path for the desired backend class" + ) + + self.backend = backend + + _backend = None # type: BaseECCBackend + + @property + def backend(self) -> 'BaseECCBackend': + if self._backend is None: + return self.get_backend() + else: + return self._backend + + @backend.setter + def backend(self, value: 'BaseECCBackend') -> None: + self._backend = value + + @classmethod + def get_backend(cls, *args: Any, **kwargs: Any) -> 'BaseECCBackend': + from client_sdk_python.packages.platon_keys.backends import get_backend + return get_backend(*args, **kwargs) + + +class BaseKey(ByteString, collections.abc.Hashable): + _raw_key = None # type: bytes + + def to_hex(self) -> str: + # Need the 'type: ignore' comment below because of + # https://github.com/python/typeshed/issues/300 + return '0x' + codecs.decode(codecs.encode(self._raw_key, 'hex'), 'ascii') # type: ignore + + def to_bytes(self) -> bytes: + return self._raw_key + + def __hash__(self) -> int: + return big_endian_to_int(keccak(self.to_bytes())) + + def __str__(self) -> str: + return self.to_hex() + + def __int__(self) -> int: + return big_endian_to_int(self._raw_key) + + def __len__(self) -> int: + # TODO: this seems wrong. + return 64 + + # Must be typed with `ignore` due to + # https://github.com/python/mypy/issues/1237 + def __getitem__(self, index: int) -> int: # type: ignore + return self._raw_key[index] + + def __eq__(self, other: Any) -> bool: + if hasattr(other, 'to_bytes'): + return self.to_bytes() == other.to_bytes() + elif is_bytes(other): + return self.to_bytes() == other + else: + return False + + def __repr__(self) -> str: + return "'{0}'".format(self.to_hex()) + + def __index__(self) -> int: + return self.__int__() + + def __hex__(self) -> str: + if sys.version_info[0] == 2: + return codecs.encode(self.to_hex(), 'ascii') + else: + return self.to_hex() + + +class PublicKey(BaseKey, LazyBackend): + def __init__(self, + public_key_bytes: bytes, + backend: 'Union[BaseECCBackend, Type[BaseECCBackend], str, None]' = None, + ) -> None: + validate_uncompressed_public_key_bytes(public_key_bytes) + + self._raw_key = public_key_bytes + super().__init__(backend=backend) + + @classmethod + def from_compressed_bytes(cls, + compressed_public_key_bytes: bytes, + backend: 'BaseECCBackend' = None, + ) -> 'PublicKey': + validate_compressed_public_key_bytes(compressed_public_key_bytes) + + if backend is None: + backend = cls.get_backend() + uncompressed_key = backend.decompress_public_key_bytes(compressed_public_key_bytes) + + return cls(uncompressed_key, backend) + + @classmethod + def from_private(cls, + private_key: 'PrivateKey', + backend: 'BaseECCBackend' = None, + ) -> 'PublicKey': + if backend is None: + backend = cls.get_backend() + return backend.private_key_to_public_key(private_key) + + @classmethod + def recover_from_msg(cls, + message: bytes, + signature: 'Signature', + backend: 'BaseECCBackend' = None, + ) -> 'PublicKey': + message_hash = keccak(message) + return cls.recover_from_msg_hash(message_hash, signature, backend) + + @classmethod + def recover_from_msg_hash(cls, + message_hash: bytes, + signature: 'Signature', + backend: 'BaseECCBackend' = None, + ) -> 'PublicKey': + if backend is None: + backend = cls.get_backend() + return backend.ecdsa_recover(message_hash, signature) + + def verify_msg(self, + message: bytes, + signature: 'Signature', + ) -> bool: + message_hash = keccak(message) + return self.verify_msg_hash(message_hash, signature) + + def verify_msg_hash(self, + message_hash: bytes, + signature: 'Signature', + ) -> bool: + return self.backend.ecdsa_verify(message_hash, signature, self) + + def to_compressed_bytes(self) -> bytes: + return self.backend.compress_public_key_bytes(self.to_bytes()) + + # + # Ethereum address conversions + # + def to_checksum_address(self) -> ChecksumAddress: + return to_checksum_address(public_key_bytes_to_address(self.to_bytes())) + + def to_address(self) -> str: + return to_normalized_address(public_key_bytes_to_address(self.to_bytes())) + + def to_canonical_address(self) -> bytes: + return public_key_bytes_to_address(self.to_bytes()) + + # PlatON address conversions + def to_bech32_address(self,hrp): + return address_bytes_to_bech32_address(public_key_bytes_to_address(self.to_bytes()),hrp) + + +class PrivateKey(BaseKey, LazyBackend): + public_key = None # type: PublicKey + + def __init__(self, + private_key_bytes: bytes, + backend: 'Union[BaseECCBackend, Type[BaseECCBackend], str, None]' = None, + ) -> None: + validate_private_key_bytes(private_key_bytes) + + self._raw_key = private_key_bytes + + self.public_key = self.backend.private_key_to_public_key(self) + super().__init__(backend=backend) + + def sign_msg(self, message: bytes) -> 'Signature': + message_hash = keccak(message) + return self.sign_msg_hash(message_hash) + + def sign_msg_hash(self, message_hash: bytes) -> 'Signature': + return self.backend.ecdsa_sign(message_hash, self) + + def sign_msg_non_recoverable(self, message: bytes) -> 'NonRecoverableSignature': + message_hash = keccak(message) + return self.sign_msg_hash_non_recoverable(message_hash) + + def sign_msg_hash_non_recoverable(self, message_hash: bytes) -> 'NonRecoverableSignature': + return self.backend.ecdsa_sign_non_recoverable(message_hash, self) + + +class BaseSignature(ByteString, LazyBackend, ABC): + _r = None # type: int + _s = None # type: int + + def __init__(self, + rs: Tuple[int, int], + backend: 'Union[BaseECCBackend, Type[BaseECCBackend], str, None]' = None + ) -> None: + for value in rs: + try: + validate_signature_r_or_s(value) + except ValidationError as error: + raise BadSignature(error) from error + + self._r, self._s = rs + super().__init__(backend=backend) + + @property + def r(self) -> int: + return self._r + + @property + def s(self) -> int: + return self._s + + @property + def rs(self) -> Tuple[int, int]: + return (self.r, self.s) + + @abstractmethod + def to_bytes(self) -> bytes: + pass + + def __bytes__(self) -> bytes: + return self.to_bytes() + + def to_hex(self) -> str: + return encode_hex(self.to_bytes()) + + def __hash__(self) -> int: + return big_endian_to_int(keccak(self.to_bytes())) + + def __str__(self) -> str: + return self.to_hex() + + def __len__(self) -> int: + return len(bytes(self)) + + def __eq__(self, other: Any) -> bool: + if hasattr(other, 'to_bytes'): + return self.to_bytes() == other.to_bytes() + elif is_bytes(other): + return self.to_bytes() == other + else: + return False + + # Must be typed with `ignore` due to + # https://github.com/python/mypy/issues/1237 + def __getitem__(self, index: int) -> int: # type: ignore + return self.to_bytes()[index] + + def __repr__(self) -> str: + return "'{0}'".format(self.to_hex()) + + def __index__(self) -> int: + return self.__int__() + + def __hex__(self) -> str: + return self.to_hex() + + def __int__(self) -> int: + return big_endian_to_int(self.to_bytes()) + + def verify_msg(self, + message: bytes, + public_key: PublicKey) -> bool: + message_hash = keccak(message) + return self.verify_msg_hash(message_hash, public_key) + + def verify_msg_hash(self, + message_hash: bytes, + public_key: PublicKey) -> bool: + return self.backend.ecdsa_verify(message_hash, self, public_key) + + +class Signature(BaseSignature): + _v = None # type: int + + def __init__(self, + signature_bytes: bytes = None, + vrs: Tuple[int, int, int] = None, + backend: 'Union[BaseECCBackend, Type[BaseECCBackend], str, None]' = None, + ) -> None: + if bool(signature_bytes) is bool(vrs): + raise TypeError("You must provide one of `signature_bytes` or `vrs`") + elif signature_bytes: + validate_recoverable_signature_bytes(signature_bytes) + r = big_endian_to_int(signature_bytes[0:32]) + s = big_endian_to_int(signature_bytes[32:64]) + v = ord(signature_bytes[64:65]) + elif vrs: + v, r, s, = vrs + else: + raise TypeError("Invariant: unreachable code path") + + super().__init__(rs=(r, s), backend=backend) + try: + self.v = v + except ValidationError as error: + raise BadSignature(str(error)) from error + + # + # v + # + @property + def v(self) -> int: + return self._v + + @v.setter + def v(self, value: int) -> None: + validate_signature_v(value) + self._v = value + + @BaseSignature.r.setter + def r(self, value: int) -> None: + validate_signature_r_or_s(value) + self._r = value + + @BaseSignature.s.setter + def s(self, value: int) -> None: + validate_signature_r_or_s(value) + self._s = value + + @property + def vrs(self) -> Tuple[int, int, int]: + return (self.v, self.r, self.s) + + def to_bytes(self) -> bytes: + vb = int_to_byte(self.v) + rb = pad32(int_to_big_endian(self.r)) + sb = pad32(int_to_big_endian(self.s)) + return b''.join((rb, sb, vb)) + + def recover_public_key_from_msg(self, message: bytes) -> PublicKey: + message_hash = keccak(message) + return self.recover_public_key_from_msg_hash(message_hash) + + def recover_public_key_from_msg_hash(self, message_hash: bytes) -> PublicKey: + return self.backend.ecdsa_recover(message_hash, self) + + def to_non_recoverable_signature(self) -> 'NonRecoverableSignature': + return NonRecoverableSignature(rs=self.rs) + + +class NonRecoverableSignature(BaseSignature): + + def __init__(self, + signature_bytes: bytes = None, + rs: Tuple[int, int] = None, + backend: 'Union[BaseECCBackend, Type[BaseECCBackend], str, None]' = None, + ) -> None: + if signature_bytes is None and rs is None: + raise TypeError("You must provide one of `signature_bytes` or `vr`") + elif signature_bytes: + validate_non_recoverable_signature_bytes(signature_bytes) + r = big_endian_to_int(signature_bytes[0:32]) + s = big_endian_to_int(signature_bytes[32:64]) + elif rs: + r, s = rs + else: + raise Exception("Invariant: unreachable code path") + + super().__init__(rs=(r, s), backend=backend) + + def to_bytes(self): + return b''.join( + pad32(int_to_big_endian(value)) + for value in self.rs + ) diff --git a/client_sdk_python/packages/platon_keys/exceptions.py b/client_sdk_python/packages/platon_keys/exceptions.py new file mode 100644 index 0000000..b6abfb7 --- /dev/null +++ b/client_sdk_python/packages/platon_keys/exceptions.py @@ -0,0 +1,6 @@ +class ValidationError(Exception): + pass + + +class BadSignature(Exception): + pass diff --git a/client_sdk_python/packages/platon_keys/main.py b/client_sdk_python/packages/platon_keys/main.py new file mode 100644 index 0000000..df2086f --- /dev/null +++ b/client_sdk_python/packages/platon_keys/main.py @@ -0,0 +1,120 @@ +from typing import (Any, Union, Type) # noqa: F401 + +from client_sdk_python.packages.platon_keys.datatypes import ( + BaseSignature, + LazyBackend, + NonRecoverableSignature, + PublicKey, + PrivateKey, + Signature, +) +from client_sdk_python.packages.platon_keys.exceptions import ( + ValidationError, +) +from client_sdk_python.packages.platon_keys.validation import ( + validate_message_hash, + validate_compressed_public_key_bytes, + validate_uncompressed_public_key_bytes, +) + + +# These must be aliased due to a scoping issue in mypy +# https://github.com/python/mypy/issues/1775 +_PublicKey = PublicKey +_PrivateKey = PrivateKey +_Signature = Signature +_NonRecoverableSignature = NonRecoverableSignature + + +class KeyAPI(LazyBackend): + # + # datatype shortcuts + # + PublicKey = PublicKey # type: Type[_PublicKey] + PrivateKey = PrivateKey # type: Type[_PrivateKey] + Signature = Signature # type: Type[_Signature] + NonRecoverableSignature = NonRecoverableSignature # type: Type[_NonRecoverableSignature] + + # + # Proxy method calls to the backends + # + def ecdsa_sign(self, + message_hash: bytes, + private_key: _PrivateKey) -> _Signature: + validate_message_hash(message_hash) + if not isinstance(private_key, PrivateKey): + raise ValidationError( + "The `private_key` must be an instance of `platon_keys.datatypes.PrivateKey`" + ) + signature = self.backend.ecdsa_sign(message_hash, private_key) + if not isinstance(signature, Signature): + raise ValidationError( + "Backend returned an invalid signature. Return value must be " + "an instance of `platon_keys.datatypes.Signature`" + ) + return signature + + def ecdsa_sign_non_recoverable(self, + message_hash: bytes, + private_key: _PrivateKey) -> _NonRecoverableSignature: + validate_message_hash(message_hash) + if not isinstance(private_key, PrivateKey): + raise ValidationError( + "The `private_key` must be an instance of `platon_keys.datatypes.PrivateKey`" + ) + signature = self.backend.ecdsa_sign_non_recoverable(message_hash, private_key) + if not isinstance(signature, NonRecoverableSignature): + raise ValidationError( + "Backend returned an invalid signature. Return value must be " + "an instance of `platon_keys.datatypes.Signature`" + ) + return signature + + def ecdsa_verify(self, + message_hash: bytes, + signature: BaseSignature, + public_key: _PublicKey) -> bool: + validate_message_hash(message_hash) + if not isinstance(public_key, PublicKey): + raise ValidationError( + "The `public_key` must be an instance of `platon_keys.datatypes.PublicKey`" + ) + if not isinstance(signature, BaseSignature): + raise ValidationError( + "The `signature` must be an instance of `platon_keys.datatypes.BaseSignature`" + ) + return self.backend.ecdsa_verify(message_hash, signature, public_key) + + def ecdsa_recover(self, + message_hash: bytes, + signature: _Signature) -> _PublicKey: + validate_message_hash(message_hash) + if not isinstance(signature, Signature): + raise ValidationError( + "The `signature` must be an instance of `platon_keys.datatypes.Signature`" + ) + public_key = self.backend.ecdsa_recover(message_hash, signature) + if not isinstance(public_key, _PublicKey): + raise ValidationError( + "Backend returned an invalid public_key. Return value must be " + "an instance of `platon_keys.datatypes.PublicKey`" + ) + return public_key + + def private_key_to_public_key(self, private_key: _PrivateKey) -> _PublicKey: + if not isinstance(private_key, PrivateKey): + raise ValidationError( + "The `private_key` must be an instance of `platon_keys.datatypes.PrivateKey`" + ) + public_key = self.backend.private_key_to_public_key(private_key) + if not isinstance(public_key, PublicKey): + raise ValidationError( + "Backend returned an invalid public_key. Return value must be " + "an instance of `platon_keys.datatypes.PublicKey`" + ) + return public_key + + +# This creates an easy to import backend which will lazily fetch whatever +# backend has been configured at runtime (as opposed to import or instantiation time). +lazy_key_api = KeyAPI(backend=None) diff --git a/client_sdk_python/packages/platon_keys/utils/__init__.py b/client_sdk_python/packages/platon_keys/utils/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/client_sdk_python/packages/platon_keys/utils/address.py b/client_sdk_python/packages/platon_keys/utils/address.py new file mode 100644 index 0000000..a531ef1 --- /dev/null +++ b/client_sdk_python/packages/platon_keys/utils/address.py @@ -0,0 +1,38 @@ +from client_sdk_python.packages.eth_utils import ( + keccak, +) +from client_sdk_python.packages.platon_keys.utils.bech32 import encode, decode, bech32_decode + +DEFAULTHRP = "lat" +BASE_ADDRESS = {'sta': '0x1000000000000000000000000000000000000002', + 'pip': '0x1000000000000000000000000000000000000005', + 'res': '0x1000000000000000000000000000000000000001', + 'del': '0x1000000000000000000000000000000000000006', + 'pen': '0x1000000000000000000000000000000000000004' + } + + +def public_key_bytes_to_address(public_key_bytes: bytes) -> bytes: + return keccak(public_key_bytes)[-20:] + + +def address_bytes_to_address(address_bytes: bytes) -> str: + witprog = list(address_bytes) + return encode(DEFAULTHRP, witprog) + + +def address_bytes_to_bech32_address(address_bytes: bytes, hrp=DEFAULTHRP) -> str: + witprog = list(address_bytes) + return encode(hrp, witprog) + + +def bech32_address_to_address_bytes(address_bytes: bytes, hrp=DEFAULTHRP) -> str: + _, data = decode(hrp, address_bytes) + return bytes(data).hex() + + +if __name__ == "__main__": + address_bytes = bytes.fromhex('3D452519bB81D4D622840F710B54e074717780A3') + address_bech32 = 'atx184zj2xdms82dvg5ypacsk48qw3ch0q9rhumxrm' + print(address_bytes_to_bech32_address(address_bytes, DEFAULTHRP)) + print(bech32_address_to_address_bytes(address_bech32, DEFAULTHRP)) \ No newline at end of file diff --git a/client_sdk_python/packages/platon_keys/utils/bech32.py b/client_sdk_python/packages/platon_keys/utils/bech32.py new file mode 100644 index 0000000..af4f5ef --- /dev/null +++ b/client_sdk_python/packages/platon_keys/utils/bech32.py @@ -0,0 +1,110 @@ +from typing import Iterable, List, Optional, Tuple, Union +from client_sdk_python.packages.eth_utils import ( + is_address, +) + +CHARSET = "qpzry9x8gf2tvdw0s3jn54khce6mua7l" + + +def bech32_polymod(values: Iterable[int]) -> int: + """Internal function that computes the Bech32 checksum.""" + generator = [0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3] + chk = 1 + for value in values: + top = chk >> 25 + chk = (chk & 0x1ffffff) << 5 ^ value + for i in range(5): + chk ^= generator[i] if ((top >> i) & 1) else 0 + return chk + + +def bech32_hrp_expand(hrp: str) -> List[int]: + """Expand the HRP into values for checksum computation.""" + return [ord(x) >> 5 for x in hrp] + [0] + [ord(x) & 31 for x in hrp] + + +def bech32_verify_checksum(hrp: str, data: Iterable[int]) -> bool: + """Verify a checksum given HRP and converted data characters.""" + return bech32_polymod(bech32_hrp_expand(hrp) + list(data)) == 1 + + +def bech32_create_checksum(hrp: str, data: Iterable[int]) -> List[int]: + """Compute the checksum values given HRP and data.""" + values = bech32_hrp_expand(hrp) + list(data) + polymod = bech32_polymod(values + [0, 0, 0, 0, 0, 0]) ^ 1 + return [(polymod >> 5 * (5 - i)) & 31 for i in range(6)] + + +def bech32_encode(hrp: str, data: Iterable[int]) -> str: + """Compute a Bech32 string given HRP and data values.""" + combined = list(data) + bech32_create_checksum(hrp, data) + return hrp + "1" + "".join([CHARSET[d] for d in combined]) + + +def bech32_decode(bech: str) -> Union[Tuple[None, None], Tuple[str, List[int]]]: + """Validate a Bech32 string, and determine HRP and data.""" + if (any(ord(x) < 33 or ord(x) > 126 for x in bech)) or ( + bech.lower() != bech and bech.upper() != bech + ): + return None, None + bech = bech.lower() + pos = bech.rfind("1") + if pos < 1 or pos > 83 or pos + 7 > len(bech): # or len(bech) > 90: + return None, None + if not all(x in CHARSET for x in bech[pos + 1 :]): + return None, None + hrp = bech[:pos] + data = [CHARSET.find(x) for x in bech[pos + 1 :]] + if not bech32_verify_checksum(hrp, data): + return None, None + return hrp, data[:-6] + + +def convertbits(data: Iterable[int], frombits: int, tobits: int, pad: bool = True) -> Optional[List[int]]: + """General power-of-2 base conversion.""" + acc = 0 + bits = 0 + ret = [] + maxv = (1 << tobits) - 1 + max_acc = (1 << (frombits + tobits - 1)) - 1 + for value in data: + if value < 0 or (value >> frombits): + return None + acc = ((acc << frombits) | value) & max_acc + bits += frombits + while bits >= tobits: + bits -= tobits + ret.append((acc >> bits) & maxv) + if pad: + if bits: + ret.append((acc << (tobits - bits)) & maxv) + elif bits >= frombits or ((acc << (tobits - bits)) & maxv): + return None + return ret + + +def decode(hrp: str, addr: str) -> Union[Tuple[None, None], Tuple[int, List[int]]]: + """Decode a segwit address.""" + hrpgot, data = bech32_decode(addr) + if hrpgot != hrp: + return None, None + assert data is not None + decoded = convertbits(data[:], 5, 8, False) + if decoded is None or len(decoded) < 2 or len(decoded) > 40: + return None, None + # if data[0] > 16: + # return None, None + if data[0] == 0 and len(decoded) != 20 and len(decoded) != 32: + return None, None + return data[0], decoded + +def encode(hrp: str, witprog: Iterable[int]) -> Optional[str]: + """Encode a segwit address.""" + five_bit_witprog = convertbits(witprog, 8, 5) + if five_bit_witprog is None: + return None + ret = bech32_encode(hrp, five_bit_witprog) + if decode(hrp, ret) == (None, None): + return None + return ret + diff --git a/client_sdk_python/packages/platon_keys/utils/der.py b/client_sdk_python/packages/platon_keys/utils/der.py new file mode 100644 index 0000000..dd31ee6 --- /dev/null +++ b/client_sdk_python/packages/platon_keys/utils/der.py @@ -0,0 +1,118 @@ +# Non-recoverable signatures are encoded using a DER sequence of two integers +# We locally implement serialization and deserialization for this specific spec +# with constrained inputs. +# This is done locally to avoid importing a 3rd-party library, in this very sensitive project. +# asn1tools and pyasn1 were used as reference APIs, see how in tests/core/test_utils_asn1.py +# +# See more about DER encodings, and ASN.1 in general, here: +# http://luca.ntop.org/Teaching/Appunti/asn1.html +# +# These methods are NOT intended for external use outside of this project. They do not +# fully validate inputs and make assumptions that are not *generally* true. + +from typing import ( + Iterator, + Tuple, +) + +from client_sdk_python.packages.eth_utils import ( + apply_to_return_value, + big_endian_to_int, + int_to_big_endian, +) + + +@apply_to_return_value(bytes) +def two_int_sequence_encoder(signature_r: int, signature_s: int) -> Iterator[int]: + """ + Encode two integers using DER, defined as: + + :: + + ECDSASpec DEFINITIONS ::= BEGIN + ECDSASignature ::= SEQUENCE { + r INTEGER, + s INTEGER + } + END + + Only a subset of integers are supported: positive, 32-byte ints. + + See: https://docs.microsoft.com/en-us/windows/desktop/seccertenroll/about-sequence + """ + # Sequence tag + yield 0x30 + + encoded1 = _encode_int(signature_r) + encoded2 = _encode_int(signature_s) + + # Sequence length + yield len(encoded1) + len(encoded2) + + yield from encoded1 + yield from encoded2 + + +def two_int_sequence_decoder(encoded: bytes) -> Tuple[int, int]: + """ + Decode bytes to two integers using DER, defined as: + + :: + + ECDSASpec DEFINITIONS ::= BEGIN + ECDSASignature ::= SEQUENCE { + r INTEGER, + s INTEGER + } + END + + Only a subset of integers are supported: positive, 32-byte ints. + + r is returned first, and s is returned second + + See: https://docs.microsoft.com/en-us/windows/desktop/seccertenroll/about-sequence + """ + if encoded[0] != 0x30: + raise ValueError("Encoded sequence must start with 0x30 byte, but got %s" % encoded[0]) + + # skip sequence length + int1, rest = _decode_int(encoded[2:]) + int2, empty = _decode_int(rest) + + if len(empty) != 0: + raise ValueError("Encoded sequence must not contain any trailing data, but had %r" % empty) + + return int1, int2 + + +@apply_to_return_value(bytes) +def _encode_int(primitive: int) -> Iterator[int]: + # See: https://docs.microsoft.com/en-us/windows/desktop/seccertenroll/about-integer + + # Integer tag + yield 0x02 + + encoded = int_to_big_endian(primitive) + if encoded[0] >= 128: + # Indicate that integer is positive (it always is, but doesn't always need the flag) + yield len(encoded) + 1 + yield 0x00 + else: + yield len(encoded) + + yield from encoded + + +def _decode_int(encoded: bytes) -> Tuple[int, bytes]: + # See: https://docs.microsoft.com/en-us/windows/desktop/seccertenroll/about-integer + + if encoded[0] != 0x02: + raise ValueError( + "Encoded value must be an integer, starting with on 0x02 byte, but got %s" % encoded[0] + ) + + length = encoded[1] + # to_int can handle leading zeros + decoded_int = big_endian_to_int(encoded[2:2 + length]) + + return decoded_int, encoded[2 + length:] diff --git a/client_sdk_python/packages/platon_keys/utils/module_loading.py b/client_sdk_python/packages/platon_keys/utils/module_loading.py new file mode 100644 index 0000000..03b4a78 --- /dev/null +++ b/client_sdk_python/packages/platon_keys/utils/module_loading.py @@ -0,0 +1,52 @@ +import operator +from typing import (Any, Tuple) +from importlib import import_module + + +def import_string(dotted_path: str) -> Any: + """ + Source: django.utils.module_loading + Import a dotted module path and return the attribute/class designated by the + last name in the path. Raise ImportError if the import failed. + """ + try: + module_path, class_name = dotted_path.rsplit('.', 1) + except ValueError: + msg = "%s doesn't look like a module path" % dotted_path + raise ImportError(msg) + + module = import_module(module_path) + + try: + return getattr(module, class_name) + except AttributeError: + msg = 'Module "%s" does not define a "%s" attribute/class' % ( + module_path, class_name) + raise ImportError(msg) + + +def split_at_longest_importable_path(dotted_path: str) -> Tuple[str, str]: + num_path_parts = len(dotted_path.split('.')) + + for i in range(1, num_path_parts): + path_parts = dotted_path.rsplit('.', i) + import_part = path_parts[0] + remainder = '.'.join(path_parts[1:]) + + try: + module = import_module(import_part) + except ImportError: + continue + + try: + operator.attrgetter(remainder)(module) + except AttributeError: + raise ImportError( + "Unable to derive appropriate import path for {0}".format( + dotted_path, + ) + ) + else: + return import_part, remainder + else: + return '', dotted_path diff --git a/client_sdk_python/packages/platon_keys/utils/numeric.py b/client_sdk_python/packages/platon_keys/utils/numeric.py new file mode 100644 index 0000000..cf2abc8 --- /dev/null +++ b/client_sdk_python/packages/platon_keys/utils/numeric.py @@ -0,0 +1,16 @@ +from client_sdk_python.packages.platon_keys.constants import ( + SECPK1_N, +) + + +def int_to_byte(value: int) -> bytes: + return bytes([value]) + + +def coerce_low_s(value: int) -> int: + """Coerce the s component of an ECDSA signature into its low-s form. + + See https://bitcoin.stackexchange.com/questions/83408/in-ecdsa-why-is-r-%E2%88%92s-mod-n-complementary-to-r-s # noqa: W501 + or https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2.md. + """ + return min(value, -value % SECPK1_N) diff --git a/client_sdk_python/packages/platon_keys/utils/padding.py b/client_sdk_python/packages/platon_keys/utils/padding.py new file mode 100644 index 0000000..58665bf --- /dev/null +++ b/client_sdk_python/packages/platon_keys/utils/padding.py @@ -0,0 +1,2 @@ +def pad32(value: bytes) -> bytes: + return value.rjust(32, b'\x00') diff --git a/client_sdk_python/packages/platon_keys/validation.py b/client_sdk_python/packages/platon_keys/validation.py new file mode 100644 index 0000000..5afc754 --- /dev/null +++ b/client_sdk_python/packages/platon_keys/validation.py @@ -0,0 +1,113 @@ +from typing import Any + +from client_sdk_python.packages.eth_utils import ( + encode_hex, + is_bytes, + is_integer, +) +from client_sdk_python.packages.eth_utils.toolz import curry + +from client_sdk_python.packages.platon_keys.constants import ( + SECPK1_N, +) +from client_sdk_python.packages.platon_keys.exceptions import ( + ValidationError, +) + + +def validate_integer(value: Any) -> None: + if not is_integer(value) or isinstance(value, bool): + raise ValidationError("Value must be a an integer. Got: {0}".format(type(value))) + + +def validate_bytes(value: Any) -> None: + if not is_bytes(value): + raise ValidationError("Value must be a byte string. Got: {0}".format(type(value))) + + +@curry +def validate_gte(value: Any, minimum: int) -> None: + validate_integer(value) + if value < minimum: + raise ValidationError( + "Value {0} is not greater than or equal to {1}".format( + value, minimum, + ) + ) + + +@curry +def validate_lte(value: Any, maximum: int) -> None: + validate_integer(value) + if value > maximum: + raise ValidationError( + "Value {0} is not less than or equal to {1}".format( + value, maximum, + ) + ) + + +validate_lt_secpk1n = validate_lte(maximum=SECPK1_N - 1) + + +def validate_bytes_length(value: bytes, expected_length: int, name: str) -> None: + actual_length = len(value) + if actual_length != expected_length: + raise ValidationError( + "Unexpected {name} length: Expected {expected_length}, but got {actual_length} " + "bytes".format( + name=name, + expected_length=expected_length, + actual_length=actual_length, + ) + ) + + +def validate_message_hash(value: Any) -> None: + validate_bytes(value) + validate_bytes_length(value, 32, "message hash") + + +def validate_uncompressed_public_key_bytes(value: Any) -> None: + validate_bytes(value) + validate_bytes_length(value, 64, "uncompressed public key") + + +def validate_compressed_public_key_bytes(value: Any) -> None: + validate_bytes(value) + validate_bytes_length(value, 33, "compressed public key") + first_byte = value[0:1] + if first_byte not in (b"\x02", b"\x03"): + raise ValidationError( + "Unexpected compressed public key format: Must start with 0x02 or 0x03, but starts " + "with {first_byte}".format( + first_byte=encode_hex(first_byte), + ) + ) + + +def validate_private_key_bytes(value: Any) -> None: + validate_bytes(value) + validate_bytes_length(value, 32, "private key") + + +def validate_recoverable_signature_bytes(value: Any) -> None: + validate_bytes(value) + validate_bytes_length(value, 65, "recoverable signature") + + +def validate_non_recoverable_signature_bytes(value: Any) -> None: + validate_bytes(value) + validate_bytes_length(value, 64, "non recoverable signature") + + +def validate_signature_v(value: int) -> None: + validate_integer(value) + validate_gte(value, minimum=0) + validate_lte(value, maximum=1) + + +def validate_signature_r_or_s(value: int) -> None: + validate_integer(value) + validate_gte(value, 0) + validate_lt_secpk1n(value) diff --git a/client_sdk_python/param_encode.py b/client_sdk_python/param_encode.py new file mode 100644 index 0000000..3d1019c --- /dev/null +++ b/client_sdk_python/param_encode.py @@ -0,0 +1,204 @@ +from client_sdk_python.fvnhash import fnv1_64 +from hexbytes import ( + HexBytes, +) +def hexstr2bytes(address: str): + pos = 0 + len_str = len(address) + if len_str % 2 != 0: + return None + len_str = round(len_str/2) + hexa = [] + for i in range(len_str): + s1 = address[pos:pos+2] + if s1 == '0x' or s1 == '0X': + pos +=2 + continue + sv = s1 + hexa.append(sv) + pos += 2 + return hexa +def tostring_hex(arr:list): + arrhex='' + if arr: + for i in arr: + arrhex= arrhex+i + return arrhex + else: + return '' +def stringtohex(str1:bytes): + strhex=[] + if str1: + for i in str1: + temp = hex(i).replace('0x','') + if len(temp) == 1: + temp = '0'+temp + strhex=strhex+[temp] + del temp + return strhex + else: return [] + +def stringfnv(str1:str): + a1 = bytes(str1, 'utf-8') + a2 = fnv1_64(a1) + a3 = hex(a2) + if len(a3) % 2: + a4 = '0'+a3.replace('0x','') + aa = hexstr2bytes(a4) + else: + aa = hexstr2bytes(a3) + return aa + +def rlp_encode(input): + if isinstance(input,list): + if len(input)==1 and input[0]=='0': return ['80'] + elif len(input) == 1 and int(input[0],16) <= 0x7f: return input + elif len(input)==0:return [] + else: + temp=encode_length(len(input), 0x80) + return (hexstr2bytes(temp.replace('0x',''))+input) + elif isinstance(input,tuple): + output = [] + for item in input: output += rlp_encode(item) + temp1=encode_length(len(output), 0xc0) + return hexstr2bytes(temp1.replace('0x','')) + output + +def encode_length(L,offset): + if L < 56: + return hex(L + offset) + elif L < 256**8: + BL = to_binary(L) + return hex(int(len(BL)/2) + offset + 55) + BL + else: + raise Exception("input too long") + +def to_binary(x): + if x == 0: + return '' + else: + tem1=(to_binary(int(x / 256))).replace('0x','') + tem2=hex(x % 256).replace('0x','') + if tem1: + if len(tem1)==1: + tem1='0'+tem1 + if tem2: + if len(tem2)==1: + tem2='0'+tem2 + return tem1+tem2 + # if x == 0: + # return '' + # else: return hex(x) + +def listcat(list1,list2): + if list2: + if isinstance(list1[0],list): + if isinstance(list2[0],list): + for i in range(len(list2)): + list1.append(list2[i]) + temp=list1 + else: + temp=[list1,list2] + else: + temp=[list1] + if isinstance(list2[0], list): + for i in range(len(list2)): + temp.append(list2[i]) + else: + temp.append(list2) + else: + temp = list1 + return temp +def tuplecat(tuple1,tuple2): + # if isinstance(tuple1[0],tuple): + # if isinstance(tuple2[0],tuple): + # temp = (tuple1,tuple2) + # else: + # temp1 = list(tuple1) + # temp1.append(tuple2) + # temp = tuple(temp1) + # elif tuple2: + # if isinstance(tuple2[0],tuple): + # temp1 = list(tuple2) + # temp1.insert(tuple1) + # temp = tuple(temp1) + # elif isinstance(tuple2,tuple): + # temp = (tuple1,tuple2) + # else: + # if isinstance(tuple2[0],list): + # temp1 = list(tuple1) + # for i in range(len(tuple2)): + # temp1.append(tuple2[i]) + # temp = tuple(temp1) + # else: + # temp1 = list(tuple1) + # temp1.append(tuple2) + # temp = tuple(temp1) + if tuple2: + if isinstance(tuple2,tuple): + temp=(tuple1,tuple2) + elif isinstance(tuple2,list): + if isinstance(tuple2[0],list): + temp=[tuple1] + for i in range(len(tuple2)): + temp.append(tuple2[i]) + temp = tuple(temp) + else: + temp=(tuple1,tuple2) + else: + temp = tuple1 + + return temp + + +def rlp_decode(input): + if len(input) == 0: + return [] + output = [] + (offset, dataLen, type) = decode_length(input) + if type is list: + output = input[offset:offset+dataLen] + output = listcat(output,rlp_decode(input[offset + dataLen:])) + elif type is tuple: + output = rlp_decode(input[offset:offset+dataLen]) + if input[offset+dataLen:]: + if isinstance(output, list): + output = tuple([output]) + output = tuplecat(output,rlp_decode(input[offset+dataLen:])) + else: + if isinstance(output, list): + output = tuple([output]) + return output + +def decode_length(input): + length = len(input) + if length == 0: + raise Exception("input is null") + prefix = int(input[0],16) + if prefix <= 0x7f: + return (0, 1, list) + elif prefix <= 0xb7 and length > prefix - 0x80: + strLen = prefix - 0x80 + return (1, strLen, list) + elif prefix <= 0xbf and length > prefix - 0xb7 and length > prefix - 0xb7 + to_integer(input[1:prefix - 0xb6]): + lenOfStrLen = prefix - 0xb7 + strLen = to_integer(input[1:lenOfStrLen+1]) + return (1 + lenOfStrLen, strLen, list) + elif prefix <= 0xf7 and length > prefix - 0xc0: + listLen = prefix - 0xc0 + return (1, listLen, tuple) + elif prefix <= 0xff and length > prefix - 0xf7 and length > prefix - 0xf7 + to_integer(input[1:prefix - 0xf6]): + lenOfListLen = prefix - 0xf7 + listLen = to_integer(input[1:lenOfListLen+1]) + return (1 + lenOfListLen, listLen, tuple) + else: + raise Exception("input don't conform RLP encoding form") + +def to_integer(b): + #获得list或tuple的真实长度 + length = len(b) + if length == 0: + raise Exception("input is null") + elif length == 1: + return int(b[0],16) + else: + return int(b[-1:],16) + to_integer(b[0:-1]) * 256 \ No newline at end of file diff --git a/client_sdk_python/parity.py b/client_sdk_python/parity.py index 7fcc638..ef7535a 100644 --- a/client_sdk_python/parity.py +++ b/client_sdk_python/parity.py @@ -1,4 +1,4 @@ -from eth_utils import ( +from client_sdk_python.packages.eth_utils import ( is_checksum_address, ) diff --git a/client_sdk_python/pip.py b/client_sdk_python/pip.py index 2c5fb55..07aec77 100644 --- a/client_sdk_python/pip.py +++ b/client_sdk_python/pip.py @@ -5,6 +5,8 @@ Module, ) from client_sdk_python.utils.transactions import send_obj_transaction, call_obj +from client_sdk_python.utils.encoding import tobech32address +from client_sdk_python.packages.platon_keys.utils.address import BASE_ADDRESS def parse_data(raw_data): @@ -18,6 +20,11 @@ class Pip(Module): # If you want to get the result of the transaction, please set it to True, # if you only want to get the transaction hash, please set it to False need_analyze = True + need_quota_gas = True + + def __init__(self, web3): + super().__init__(web3) + self.pipAddress = tobech32address(self.web3.net_type, BASE_ADDRESS['pip']) def submitText(self, verifier, pip_id, pri_key, transaction_cfg=None): """ @@ -36,7 +43,7 @@ def submitText(self, verifier, pip_id, pri_key, transaction_cfg=None): if is not need analyze return transaction hash """ data = rlp.encode([rlp.encode(int(2000)), rlp.encode(bytes.fromhex(verifier)), rlp.encode(pip_id)]) - return send_obj_transaction(self, data, self.web3.pipAddress, pri_key, transaction_cfg) + return send_obj_transaction(self, data, self.pipAddress, pri_key, transaction_cfg) def submitVersion(self, verifier, pip_id, new_version, end_voting_rounds, pri_key, transaction_cfg=None): """ @@ -64,7 +71,7 @@ def submitVersion(self, verifier, pip_id, new_version, end_voting_rounds, pri_ke """ data = rlp.encode([rlp.encode(int(2001)), rlp.encode(bytes.fromhex(verifier)), rlp.encode(pip_id), rlp.encode(int(new_version)), rlp.encode(int(end_voting_rounds))]) - return send_obj_transaction(self, data, self.web3.pipAddress, pri_key, transaction_cfg) + return send_obj_transaction(self, data, self.pipAddress, pri_key, transaction_cfg) def submitParam(self, verifier, pip_id, module, name, new_value, pri_key, transaction_cfg=None): """ @@ -87,7 +94,7 @@ def submitParam(self, verifier, pip_id, module, name, new_value, pri_key, transa """ data = rlp.encode([rlp.encode(int(2002)), rlp.encode(bytes.fromhex(verifier)), rlp.encode(pip_id), rlp.encode(module), rlp.encode(name), rlp.encode(new_value)]) - return send_obj_transaction(self, data, self.web3.pipAddress, pri_key, transaction_cfg) + return send_obj_transaction(self, data, self.pipAddress, pri_key, transaction_cfg) def submitCancel(self, verifier, pip_id, end_voting_rounds, tobe_canceled_proposal_id, pri_key, transaction_cfg=None): """ @@ -115,7 +122,7 @@ def submitCancel(self, verifier, pip_id, end_voting_rounds, tobe_canceled_propos data = rlp.encode([rlp.encode(int(2005)), rlp.encode(bytes.fromhex(verifier)), rlp.encode(pip_id), rlp.encode(int(end_voting_rounds)), rlp.encode(bytes.fromhex(tobe_canceled_proposal_id))]) - return send_obj_transaction(self, data, self.web3.pipAddress, pri_key, transaction_cfg) + return send_obj_transaction(self, data, self.pipAddress, pri_key, transaction_cfg) def vote(self, verifier, proposal_id, option, program_version, version_sign, pri_key, transaction_cfg=None): """ @@ -142,7 +149,7 @@ def vote(self, verifier, proposal_id, option, program_version, version_sign, pri version_sign = version_sign[2:] data = rlp.encode([rlp.encode(int(2003)), rlp.encode(bytes.fromhex(verifier)), rlp.encode(bytes.fromhex(proposal_id)), rlp.encode(option), rlp.encode(int(program_version)), rlp.encode(bytes.fromhex(version_sign))]) - return send_obj_transaction(self, data, self.web3.pipAddress, pri_key, transaction_cfg) + return send_obj_transaction(self, data, self.pipAddress, pri_key, transaction_cfg) def declareVersion(self, active_node, program_version, version_sign, pri_key, transaction_cfg=None): """ @@ -165,7 +172,7 @@ def declareVersion(self, active_node, program_version, version_sign, pri_key, tr version_sign = version_sign[2:] data = rlp.encode([rlp.encode(int(2004)), rlp.encode(bytes.fromhex(active_node)), rlp.encode(int(program_version)), rlp.encode(bytes.fromhex(version_sign))]) - return send_obj_transaction(self, data, self.web3.pipAddress, pri_key, transaction_cfg) + return send_obj_transaction(self, data, self.pipAddress, pri_key, transaction_cfg) def getProposal(self, proposal_id, from_address=None): """ @@ -178,7 +185,7 @@ def getProposal(self, proposal_id, from_address=None): if proposal_id[:2] == '0x': proposal_id = proposal_id[2:] data = rlp.encode([rlp.encode(int(2100)), rlp.encode(bytes.fromhex(proposal_id))]) - return parse_data(call_obj(self, from_address, self.web3.pipAddress, data)) + return parse_data(call_obj(self, from_address, self.pipAddress, data)) def getTallyResult(self, proposal_id, from_address=None): """ @@ -191,7 +198,7 @@ def getTallyResult(self, proposal_id, from_address=None): if proposal_id[:2] == '0x': proposal_id = proposal_id[2:] data = rlp.encode([rlp.encode(int(2101)), rlp.encode(bytes.fromhex(proposal_id))]) - return parse_data(call_obj(self, from_address, self.web3.pipAddress, data)) + return parse_data(call_obj(self, from_address, self.pipAddress, data)) def getAccuVerifiersCount(self, proposal_id, block_hash, from_address=None): """ @@ -208,7 +215,7 @@ def getAccuVerifiersCount(self, proposal_id, block_hash, from_address=None): block_hash = block_hash[2:] data = rlp.encode( [rlp.encode(int(2105)), rlp.encode(bytes.fromhex(proposal_id)), rlp.encode(bytes.fromhex(block_hash))]) - return parse_data(call_obj(self, from_address, self.web3.pipAddress, data)) + return parse_data(call_obj(self, from_address, self.pipAddress, data)) def listProposal(self, from_address=None): """ @@ -218,7 +225,7 @@ def listProposal(self, from_address=None): todo fill """ data = rlp.encode([rlp.encode(int(2102))]) - return parse_data(call_obj(self, from_address, self.web3.pipAddress, data)) + return parse_data(call_obj(self, from_address, self.pipAddress, data)) def getActiveVersion(self, from_address=None): """ @@ -228,7 +235,7 @@ def getActiveVersion(self, from_address=None): todo fill """ data = rlp.encode([rlp.encode(int(2103))]) - return parse_data(call_obj(self, from_address, self.web3.pipAddress, data)) + return parse_data(call_obj(self, from_address, self.pipAddress, data)) def getGovernParamValue(self, module, name, from_address=None): """ @@ -239,7 +246,7 @@ def getGovernParamValue(self, module, name, from_address=None): :return: """ data = rlp.encode([rlp.encode(int(2104)), rlp.encode(module), rlp.encode(name)]) - return parse_data(call_obj(self, from_address, self.web3.pipAddress, data)) + return parse_data(call_obj(self, from_address, self.pipAddress, data)) def listGovernParam(self, module=None, from_address=None): """ @@ -252,4 +259,4 @@ def listGovernParam(self, module=None, from_address=None): if module is None: module = "" data = rlp.encode([rlp.encode(int(2106)), rlp.encode(module)]) - return parse_data(call_obj(self, from_address, self.web3.pipAddress, data)) + return parse_data(call_obj(self, from_address, self.pipAddress, data)) diff --git a/client_sdk_python/ppos.py b/client_sdk_python/ppos.py index bd05497..d24ede8 100644 --- a/client_sdk_python/ppos.py +++ b/client_sdk_python/ppos.py @@ -8,19 +8,30 @@ from eth_utils.hexadecimal import remove_0x_prefix from client_sdk_python.utils.encoding import parse_str from client_sdk_python.utils.transactions import send_obj_transaction, call_obj -from platon_account.internal.transactions import bech32_address_bytes +from client_sdk_python.packages.platon_account.internal.transactions import bech32_address_bytes +from client_sdk_python.packages.platon_keys.utils.address import BASE_ADDRESS +from client_sdk_python.utils.encoding import tobech32address class Ppos(Module): # If you want to get the result of the transaction, please set it to True, # if you only want to get the transaction hash, please set it to False need_analyze = True + need_quota_gas = True - def createStaking(self, typ, benifit_address, node_id, external_id, node_name, website, details, amount, - program_version, program_version_sign, bls_pubkey, bls_proof, pri_key, reward_per, transaction_cfg=None): + def __init__(self, web3): + super().__init__(web3) + self.stakingAddress = tobech32address(self.web3.net_type, BASE_ADDRESS['sta']) + self.delegateRewardAddress = tobech32address(self.web3.net_type, BASE_ADDRESS['del']) + self.penaltyAddress = tobech32address(self.web3.net_type, BASE_ADDRESS['pen']) + self.restrictingAddress = tobech32address(self.web3.net_type, BASE_ADDRESS['res']) + + def createStaking(self, typ, benifit_address, node_id, external_id, node_name, website, details, amount,program_version, + program_version_sign, bls_pubkey, bls_proof, pri_key, reward_per, transaction_cfg=None): """ Initiate Staking - :param typ: Indicates whether the account free amount or the account's lock amount is used for staking, 0: free amount; 1: lock amount + :param typ: Indicates whether the account free amount or the account's lock amount is used for staking, 0: free amount; 1: lock amount; + 2: Give priority to lock amount , use free amount provided that staking amount over lock amount :param benifit_address: Income account for accepting block rewards and staking rewards :param node_id: The idled node Id (also called the candidate's node Id) :param external_id: External Id (with length limit, Id for the third party to pull the node description) @@ -53,7 +64,7 @@ def createStaking(self, typ, benifit_address, node_id, external_id, node_name, w rlp.encode(amount), rlp.encode(reward_per), rlp.encode(program_version), rlp.encode(bytes.fromhex(program_version_sign)), rlp.encode(bytes.fromhex(bls_pubkey)), rlp.encode(bytes.fromhex(bls_proof))])).hex() - return send_obj_transaction(self, data, self.web3.stakingAddress, pri_key, transaction_cfg) + return send_obj_transaction(self, data, self.stakingAddress, pri_key, transaction_cfg) def editCandidate(self, benifit_address, node_id, external_id, node_name, website, details, pri_key, reward_per, transaction_cfg=None): """ @@ -78,16 +89,21 @@ def editCandidate(self, benifit_address, node_id, external_id, node_name, websit """ # if benifit_address[:2] == '0x': # benifit_address = benifit_address[2:] - benifit_address = bech32_address_bytes(benifit_address) - data = HexBytes(rlp.encode([rlp.encode(int(1001)), rlp.encode(benifit_address), rlp.encode(bytes.fromhex(node_id)), - rlp.encode(reward_per), - rlp.encode(external_id), rlp.encode(node_name), rlp.encode(website), rlp.encode(details)])).hex() - return send_obj_transaction(self, data, self.web3.stakingAddress, pri_key, transaction_cfg) + rlp_benifit_address = rlp.encode(bech32_address_bytes(benifit_address)) if benifit_address else b'' + rlp_external_id = rlp.encode(external_id) if external_id else b'' + rlp_node_name = rlp.encode(node_name) if node_name else b'' + rlp_website = rlp.encode(website) if website else b'' + rlp_details = rlp.encode(details) if details else b'' + rlp_reward_per = rlp.encode(reward_per) if reward_per else b'' + data = HexBytes(rlp.encode([rlp.encode(int(1001)), rlp_benifit_address, rlp.encode(bytes.fromhex(node_id)), rlp_reward_per, rlp_external_id, + rlp_node_name, rlp_website, rlp_details])).hex() + return send_obj_transaction(self, data, self.stakingAddress, pri_key, transaction_cfg) def increaseStaking(self, typ, node_id, amount, pri_key, transaction_cfg=None): """ Increase staking - :param typ: Indicates whether the account free amount or the account's lock amount is used for staking, 0: free amount; 1: lock amount + :param typ: Indicates whether the account free amount or the account's lock amount is used for staking, 0: free amount; 1: lock amount; + 2: Give priority to lock amount , use free amount provided that staking amount over lock amount :param node_id: The idled node Id (also called the candidate's node Id) :param amount: staking von (unit:von, 1LAT = 10**18 von) :param pri_key: Private key for transaction @@ -102,7 +118,7 @@ def increaseStaking(self, typ, node_id, amount, pri_key, transaction_cfg=None): if is not need analyze return transaction hash """ data = HexBytes(rlp.encode([rlp.encode(int(1002)), rlp.encode(bytes.fromhex(node_id)), rlp.encode(typ), rlp.encode(amount)])).hex() - return send_obj_transaction(self, data, self.web3.stakingAddress, pri_key, transaction_cfg) + return send_obj_transaction(self, data, self.stakingAddress, pri_key, transaction_cfg) def withdrewStaking(self, node_id, pri_key, transaction_cfg=None): """ @@ -120,7 +136,7 @@ def withdrewStaking(self, node_id, pri_key, transaction_cfg=None): if is not need analyze return transaction hash """ data = rlp.encode([rlp.encode(int(1003)), rlp.encode(bytes.fromhex(node_id))]) - return send_obj_transaction(self, data, self.web3.stakingAddress, pri_key, transaction_cfg) + return send_obj_transaction(self, data, self.stakingAddress, pri_key, transaction_cfg) def delegate(self, typ, node_id, amount, pri_key, transaction_cfg=None): """ @@ -140,7 +156,7 @@ def delegate(self, typ, node_id, amount, pri_key, transaction_cfg=None): if is not need analyze return transaction hash """ data = rlp.encode([rlp.encode(int(1004)), rlp.encode(typ), rlp.encode(bytes.fromhex(node_id)), rlp.encode(amount)]) - return send_obj_transaction(self, data, self.web3.stakingAddress, pri_key, transaction_cfg) + return send_obj_transaction(self, data, self.stakingAddress, pri_key, transaction_cfg) def withdrewDelegate(self, staking_blocknum, node_id, amount, pri_key, transaction_cfg=None): """ @@ -160,7 +176,7 @@ def withdrewDelegate(self, staking_blocknum, node_id, amount, pri_key, transacti if is not need analyze return transaction hash """ data = rlp.encode([rlp.encode(int(1005)), rlp.encode(staking_blocknum), rlp.encode(bytes.fromhex(node_id)), rlp.encode(amount)]) - return send_obj_transaction(self, data, self.web3.stakingAddress, pri_key, transaction_cfg) + return send_obj_transaction(self, data, self.stakingAddress, pri_key, transaction_cfg) def getVerifierList(self, from_address=None): """ @@ -170,7 +186,7 @@ def getVerifierList(self, from_address=None): todo fill """ data = rlp.encode([rlp.encode(int(1100))]) - raw_data = call_obj(self, from_address, self.web3.stakingAddress, data) + raw_data = call_obj(self, from_address, self.stakingAddress, data) parse = parse_str(raw_data) try: raw_data = parse["Ret"] @@ -187,7 +203,7 @@ def getValidatorList(self, from_address=None): todo fill """ data = rlp.encode([rlp.encode(int(1101))]) - raw_data = call_obj(self, from_address, self.web3.stakingAddress, data) + raw_data = call_obj(self, from_address, self.stakingAddress, data) parse = parse_str(raw_data) try: raw_data = parse["Ret"] @@ -204,7 +220,7 @@ def getCandidateList(self, from_address=None): todo fill """ data = rlp.encode([rlp.encode(int(1102))]) - raw_data = call_obj(self, from_address, self.web3.stakingAddress, data) + raw_data = call_obj(self, from_address, self.stakingAddress, data) parse = parse_str(raw_data) try: raw_data = parse["Ret"] @@ -227,7 +243,7 @@ def getRelatedListByDelAddr(self, del_addr, from_address=None): """ del_addr = bech32_address_bytes(del_addr) data = rlp.encode([rlp.encode(int(1103)), rlp.encode(del_addr)]) - raw_data = call_obj(self, from_address, self.web3.stakingAddress, data) + raw_data = call_obj(self, from_address, self.stakingAddress, data) return parse_str(raw_data) def getDelegateInfo(self, staking_blocknum, del_address, node_id, from_address=None): @@ -242,7 +258,7 @@ def getDelegateInfo(self, staking_blocknum, del_address, node_id, from_address=N """ del_address = bech32_address_bytes(del_address) data = rlp.encode([rlp.encode(int(1104)), rlp.encode(staking_blocknum), rlp.encode(del_address), rlp.encode(bytes.fromhex(node_id))]) - raw_data = call_obj(self, from_address, self.web3.stakingAddress, data) + raw_data = call_obj(self, from_address, self.stakingAddress, data) receive = json.loads(str(raw_data, encoding="utf8")) try: raw_data_dict = receive["Ret"] @@ -265,7 +281,7 @@ def getCandidateInfo(self, node_id, from_address=None): todo fill """ data = rlp.encode([rlp.encode(int(1105)), rlp.encode(bytes.fromhex(node_id))]) - raw_data = call_obj(self, from_address, self.web3.stakingAddress, data) + raw_data = call_obj(self, from_address, self.stakingAddress, data) parse = str(raw_data, encoding="utf8").replace('\\', '').replace('"{', '{').replace('}"', '}') receive = json.loads(parse) try: @@ -299,7 +315,7 @@ def reportDuplicateSign(self, typ, data, pri_key, transaction_cfg=None): if is not need analyze return transaction hash """ data = rlp.encode([rlp.encode(int(3000)), rlp.encode(typ), rlp.encode(data)]) - return send_obj_transaction(self, data, self.web3.penaltyAddress, pri_key, transaction_cfg) + return send_obj_transaction(self, data, self.penaltyAddress, pri_key, transaction_cfg) def checkDuplicateSign(self, typ, node_id, block_number, from_address=None): """ @@ -312,7 +328,7 @@ def checkDuplicateSign(self, typ, node_id, block_number, from_address=None): todo fill """ data = rlp.encode([rlp.encode(int(3001)), rlp.encode(int(typ)), rlp.encode(bytes.fromhex(node_id)), rlp.encode(block_number)]) - raw_data = call_obj(self, from_address, self.web3.penaltyAddress, data) + raw_data = call_obj(self, from_address, self.penaltyAddress, data) receive = str(raw_data, encoding="ISO-8859-1") if receive == "": return receive @@ -353,7 +369,7 @@ def createRestrictingPlan(self, account, plan, pri_key, transaction_cfg=None): plan_list.append(v) rlp_list = rlp.encode(plan_list) data = rlp.encode([rlp.encode(int(4000)), rlp.encode(account), rlp_list]) - return send_obj_transaction(self, data, self.web3.restrictingAddress, pri_key, transaction_cfg) + return send_obj_transaction(self, data, self.restrictingAddress, pri_key, transaction_cfg) def getRestrictingInfo(self, account, from_address=None): """ @@ -367,7 +383,7 @@ def getRestrictingInfo(self, account, from_address=None): # account = account[2:] account = bech32_address_bytes(account) data = rlp.encode([rlp.encode(int(4100)), rlp.encode(account)]) - raw_data = call_obj(self, from_address, self.web3.restrictingAddress, data) + raw_data = call_obj(self, from_address, self.restrictingAddress, data) receive = json.loads(str(raw_data, encoding="ISO-8859-1")) try: raw_data_dict = receive["Ret"] @@ -383,7 +399,7 @@ def getRestrictingInfo(self, account, from_address=None): def getPackageReward(self, from_address=None): data = rlp.encode([rlp.encode(int(1200))]) - raw_data = call_obj(self, from_address, self.web3.stakingAddress, data) + raw_data = call_obj(self, from_address, self.stakingAddress, data) receive = json.loads(str(raw_data, encoding="ISO-8859-1")) ret = receive["Ret"] receive["Ret"] = int(str(ret), 16) @@ -391,7 +407,7 @@ def getPackageReward(self, from_address=None): def getStakingReward(self, from_address=None): data = rlp.encode([rlp.encode(int(1201))]) - raw_data = call_obj(self, from_address, self.web3.stakingAddress, data) + raw_data = call_obj(self, from_address, self.stakingAddress, data) receive = json.loads(str(raw_data, encoding="ISO-8859-1")) ret = receive["Ret"] receive["Ret"] = int(str(ret), 16) @@ -399,7 +415,7 @@ def getStakingReward(self, from_address=None): def getAvgPackTime(self, from_address=None): data = rlp.encode([rlp.encode(int(1202))]) - raw_data = call_obj(self, from_address, self.web3.stakingAddress, data) + raw_data = call_obj(self, from_address, self.stakingAddress, data) receive = json.loads(str(raw_data, encoding="ISO-8859-1")) return receive @@ -408,7 +424,7 @@ def getDelegateReward(self, from_address, node_ids=[]): tmp_from_address = bech32_address_bytes(from_address) data = [rlp.encode(int(5100)), rlp.encode(tmp_from_address), rlp.encode(node_id_bytes)] data = rlp.encode(data) - raw_data = call_obj(self, from_address, self.web3.delegateRewardAddress, data) + raw_data = call_obj(self, from_address, self.delegateRewardAddress, data) receive = json.loads(str(raw_data, encoding="ISO-8859-1")) try: raw_data_dict = receive["Ret"] @@ -422,4 +438,4 @@ def getDelegateReward(self, from_address, node_ids=[]): def withdrawDelegateReward(self, pri_key, transaction_cfg=None): data = rlp.encode([rlp.encode(int(5000))]) - return send_obj_transaction(self, data, self.web3.delegateRewardAddress, pri_key, transaction_cfg) \ No newline at end of file + return send_obj_transaction(self, data, self.delegateRewardAddress, pri_key, transaction_cfg) diff --git a/client_sdk_python/providers/base.py b/client_sdk_python/providers/base.py index 012e9b7..0e1c808 100644 --- a/client_sdk_python/providers/base.py +++ b/client_sdk_python/providers/base.py @@ -1,6 +1,6 @@ import itertools -from eth_utils import ( +from client_sdk_python.packages.eth_utils import ( to_bytes, to_text, ) diff --git a/client_sdk_python/providers/eth_tester/defaults.py b/client_sdk_python/providers/eth_tester/defaults.py index 4a1ac24..e5fc2b4 100644 --- a/client_sdk_python/providers/eth_tester/defaults.py +++ b/client_sdk_python/providers/eth_tester/defaults.py @@ -8,7 +8,7 @@ TransactionNotFound, ValidationError, ) -from eth_utils import ( +from client_sdk_python.packages.eth_utils import ( decode_hex, encode_hex, is_null, diff --git a/client_sdk_python/providers/eth_tester/middleware.py b/client_sdk_python/providers/eth_tester/middleware.py index ae53f0b..bc7de07 100644 --- a/client_sdk_python/providers/eth_tester/middleware.py +++ b/client_sdk_python/providers/eth_tester/middleware.py @@ -1,6 +1,6 @@ import operator -from eth_utils import ( +from client_sdk_python.packages.eth_utils import ( is_dict, is_hex, is_string, diff --git a/client_sdk_python/providers/rpc.py b/client_sdk_python/providers/rpc.py index 5809880..94b1571 100644 --- a/client_sdk_python/providers/rpc.py +++ b/client_sdk_python/providers/rpc.py @@ -1,7 +1,7 @@ import logging import os -from eth_utils import ( +from client_sdk_python.packages.eth_utils import ( to_dict, ) diff --git a/client_sdk_python/providers/tester.py b/client_sdk_python/providers/tester.py index 53349b7..3b2d401 100644 --- a/client_sdk_python/providers/tester.py +++ b/client_sdk_python/providers/tester.py @@ -2,7 +2,7 @@ make_server, ) -from eth_utils import ( +from client_sdk_python.packages.eth_utils import ( decode_hex, is_integer, is_string, diff --git a/client_sdk_python/rlpencode.py b/client_sdk_python/rlpencode.py new file mode 100644 index 0000000..81d44d0 --- /dev/null +++ b/client_sdk_python/rlpencode.py @@ -0,0 +1,71 @@ +def rlp_encode(input): + if isinstance(input,list): + if len(input) == 1 and ord(input[0]) <= 0x7f: return input + else: + temp=encode_length(len(input), 0x80) + return ([temp.replace('0x','')]+input) + elif isinstance(input,tuple): + output = [] + for item in input: output += rlp_encode(item) + return encode_length(len(output), 0xc0) + output + +def encode_length(L,offset): + if L < 56: + return hex(L + offset) + elif L < 256**8: + BL = to_binary(L) + return hex(len(BL) + offset + 55) + BL + else: + raise Exception("input too long") + +def to_binary(x): + if x == 0: + return '' + else: + return to_binary(int(x / 256)) + hex(x % 256) + + +# def rlp_decode(input): +# if len(input) == 0: +# return +# output = '' +# (offset, dataLen, type) = decode_length(input) +# if type is str: +# output = instantiate_str(substr(input, offset, dataLen)) +# elif type is list: +# output = instantiate_list(substr(input, offset, dataLen)) +# output + rlp_decode(substr(input, offset + dataLen)) +# return output +# +# def decode_length(input): +# length = len(input) +# if length == 0: +# raise Exception("input is null") +# prefix = ord(input[0]) +# if prefix <= 0x7f: +# return (0, 1, str) +# elif prefix <= 0xb7 and length > prefix - 0x80: +# strLen = prefix - 0x80 +# return (1, strLen, str) +# elif prefix <= 0xbf and length > prefix - 0xb7 and length > prefix - 0xb7 + to_integer(substr(input, 1, prefix - 0xb7)): +# lenOfStrLen = prefix - 0xb7 +# strLen = to_integer(substr(input, 1, lenOfStrLen)) +# return (1 + lenOfStrLen, strLen, str) +# elif prefix <= 0xf7 and length > prefix - 0xc0: +# listLen = prefix - 0xc0; +# return (1, listLen, list) +# elif prefix <= 0xff and length > prefix - 0xf7 and length > prefix - 0xf7 + to_integer(substr(input, 1, prefix - 0xf7)): +# lenOfListLen = prefix - 0xf7 +# listLen = to_integer(substr(input, 1, lenOfListLen)) +# return (1 + lenOfListLen, listLen, list) +# else: +# raise Exception("input don't conform RLP encoding form") +# +# def to_integer(b): +# length = len(b) +# if length == 0: +# raise Exception("input is null") +# elif length == 1: +# return ord(b[0]) +# else: +# return ord(substr(b, -1)) + to_integer(substr(b, 0, -1)) * 256 \ No newline at end of file diff --git a/client_sdk_python/string2bytetest.py b/client_sdk_python/string2bytetest.py new file mode 100644 index 0000000..0b6fa2e --- /dev/null +++ b/client_sdk_python/string2bytetest.py @@ -0,0 +1,62 @@ +from client_sdk_python.fvnhash import fnv1_64 +from client_sdk_python.param_encode import (rlp_encode,to_binary,) +from hexbytes import ( + HexBytes, +) +# from client_sdk_python.utils.encoding import ( +# str2bytes,encodeaddress,tobech32address,) + +def hexstr2bytes(address: str): + pos = 0 + len_str = len(address) + if len_str % 2 != 0: + return None + len_str = round(len_str/2) + hexa = [] + for i in range(len_str): + s1 = address[pos:pos+2] + if s1 == '0x' or s1 == '0X': + pos +=2 + continue + sv = s1 + hexa.append(sv) + pos += 2 + return hexa +def tostring_hex(arr:list): + arrhex='' + if arr: + for i in arr: + arrhex= arrhex+i + return arrhex + else : + return '' +def stringtohex(str1:bytes): + strhex=[] + if str1: + for i in str1: + strhex=strhex+[hex(i).replace('0x','')] + return strhex + else: return [] +# uin=257 +# uina=[] +# while (uin & 0xff): +# temp=[] +# temp=(hex(uin & 0xff)).replace('0x','') +# if len(temp)==1: +# temp='0'+temp +# uina.append(temp) +# uin=uin >> 8 + +data='0x0061736d0100000001470d60017f017f60027f7f0060000060017f0060037f7f7f0060047f7f7f7f0060027f7f017f60037f7f7f017f60047f7f7f7f017f60017f017e60027f7e006000017f60017e017f02a9010703656e760c706c61746f6e5f70616e6963000203656e7617706c61746f6e5f6765745f696e7075745f6c656e677468000b03656e7610706c61746f6e5f6765745f696e707574000303656e7617706c61746f6e5f6765745f73746174655f6c656e677468000603656e7610706c61746f6e5f6765745f7374617465000803656e7610706c61746f6e5f7365745f7374617465000503656e760d706c61746f6e5f72657475726e000103201f0202000704090903000300000c010a020803000001070106010104020000050405017001010105030100020608017f0141b088040b073904066d656d6f72790200115f5f7761736d5f63616c6c5f63746f727300070f5f5f66756e63735f6f6e5f65786974001606696e766f6b6500080ad02a1f040010220b940202047f017e230041d0006b22012400102210012200100922021002200141386a200141086a20022000100a22004100100b02400240200141386a100c2204500d00418008100d20045104402000100e200141386a100f10100c020b418508100d200451044020001011410247044010000b200141386a20004101100b200141386a100c2104200141386a100f210020012004370348200010100c020b418908100d2004520d002000100e200141206a100f210220012903302104200141386a10122200200410131014200020041015200028020c200041106a28020047044010000b200028020020002802041006200028020c22030440200020033602100b200210100c010b10000b1016200141d0006a24000b9b0101047f230041106b220124002001200036020c2000047f41a408200041086a2202411076220041a4082802006a220336020041a00841a008280200220420026a41076a417871220236020002400240200341107420024d044041a408200341016a360200200041016a21000c010b2000450d010b200040000d0010000b20042001410c6a4104101c41086a0541000b2100200141106a240020000b0c00200020012002411c10170bc90202067f017e230041106b220324002001280208220520024b0440200341086a2001101d20012003280208200328020c101e36020c20032001101d410021052001027f410020032802002207450d001a410020032802042208200128020c2206490d001a200820062006417f461b210420070b360210200141146a2004360200200141003602080b200141106a210603402001280214210402402005200249044020040d01410021040b200020062802002004411410171a200341106a24000f0b20032001101d41002104027f410020032802002205450d001a410020032802042208200128020c2207490d001a200820076b2104200520076a0b2105200120043602142001200536021020032006410020052004101e10252001200329030022093702102001200128020c2009422088a76a36020c2001200128020841016a22053602080c000b000bad0302057f017e20001018024002402000280204450d00200010180240200028020022012c0000220241004e044020020d010c020b200241807f460d00200241ff0171220341b7014d0440200028020441014d04401000200028020021010b20012d00010d010c020b200341bf014b0d012000280204200241ff017141ca7e6a22024d04401000200028020021010b200120026a2d0000450d010b2000280204450d0020012d000041c001490d010b10000b200010192204200028020422014b04401000200028020421010b20002802002105024002400240200104404100210320052c00002200417f4a0d01027f200041ff0171220341bf014d04404100200041ff017141b801490d011a200341c97e6a0c010b4100200041ff017141f801490d001a200341897e6a0b41016a21030c010b4101210320050d00410021000c010b41002100200320046a20014b0d0020012004490d004100210220012003490d01200320056a2102200120036b20042004417f461b22004109490d0110000c010b410021020b0340200004402000417f6a210020023100002006420886842106200241016a21020c010b0b20060b3901027e42a5c688a1c89ca7f94b210103402000300000220250450440200041016a2100200142b383808080207e20028521010c010b0b20010b0e0020001011410147044010000b0bda0101077f230041306b22052400200042d1f0fad48ae09ad34537030820004200370300200541186a1012220220002903081015200228020c200241106a28020047044010000b02400240200228020022062002280204220710032204450d002004101a21030340200120036a41003a00002004200141016a2201470d000b20062007200320011004417f460d0020002005200341016a200120036a2003417f736a100a100c3703100c010b410021040b200228020c22010440200220013602100b2004450440200020002903003703100b200541306a240020000bb40201097f230041306b22032400200341186a10122202200029030810131014200220002903081015200228020c200241106a28020047044010000b20022802042105200228020021062003101221012000290310101321074101101a220441fe013a0000200128020c200141106a28020047044010000b2001280204220841016a220920012802084b047f20012009101b20012802040520080b20012802006a20044101101c1a2001200128020441016a3602042001200441016a200720046b6a10142001200029031010150240200128020c2001280210460440200128020021000c010b100020012802002100200128020c2001280210460d0010000b20062005200020012802041005200128020c22000440200120003602100b200228020c22010440200220013602100b200341306a24000b800101047f230041106b2201240002402000280204450d0020002802002d000041c001490d00200141086a2000101d200128020c210003402000450d01200141002001280208220320032000101e22046a20034520002004497222031b3602084100200020046b20031b2100200241016a21020c000b000b200141106a240020020b2900200041003602082000420037020020004100101b200041146a41003602002000420037020c20000b7002027f017e4101210120004280015a047f41002101034020002003845045044020034238862000420888842100200141016a2101200342088821030c010b0b024020014138490d002001210203402002450d01200141016a2101200241087621020c000b000b200141016a0520010b0b13002000280208200149044020002001101b0b0bc10402057f027e024020015004402000418001101f0c010b20014280015a044020012108034020072008845045044020074238862008420888842108200241016a2102200742088821070c010b0b0240200241384f04402002210403402004044020044108762104200341016a21030c010b0b200341c9004f044010000b2000200341b77f6a41ff0171101f2000200028020420036a1020200028020420002802006a417f6a21032002210403402004450d02200320043a0000200441087621042003417f6a21030c000b000b200020024180017341ff0171101f0b2000200028020420026a1020200028020420002802006a417f6a21024200210703402001200784500d02200220013c0000200742388620014208888421012002417f6a2102200742088821070c000b000b20002001a741ff0171101f0b0340024020002802102202200028020c460d00200241786a2802004504401000200028021021020b200241786a22042004280200417f6a220336020020030d002000200436021041002104200028020422062002417c6a28020022056b2203210203402002044020024108762102200441016a21040c010b0b20004101200441016a20034138491b220220066a1020200028020020056a220620026a200620031021200341374d0440200028020020056a200341406a3a00000c020b200441084d0440200028020020056a200441776a3a0000200028020020056a20046a210203402003450d03200220033a0000200341087621032002417f6a21020c000b000510000c020b000b0b0b880101037f4190084101360200419408280200210003402000044003404198084198082802002201417f6a220236020020014101484504404190084100360200200020024102746a22004184016a280200200041046a280200110300419008410136020041940828020021000c010b0b4198084120360200419408200028020022003602000c010b0b0b730020004200370210200042ffffffff0f370208200020023602042000200136020002402003410871450d002000102320024f0d002003410471044010000c010b200042003702000b02402003411071450d002000102320024d0d0020034104710440100020000f0b200042003702000b20000b4101017f200028020445044010000b0240200028020022012d0000418101470d00200028020441014d047f100020002802000520010b2c00014100480d0010000b0bff0201037f200028020445044041000f0b2000101841012102024020002802002c00002201417f4a0d00200141ff0171220341b7014d0440200341807f6a0f0b02400240200141ff0171220141bf014d0440024020002802042201200341c97e6a22024d047f100020002802040520010b4102490d0020002802002d00010d0010000b200241054f044010000b20002802002d000145044010000b4100210241b7012101034020012003460440200241384f0d030c0405200028020020016a41ca7e6a2d00002002410874722102200141016a21010c010b000b000b200141f7014d0440200341c07e6a0f0b024020002802042201200341897e6a22024d047f100020002802040520010b4102490d0020002802002d00010d0010000b200241054f044010000b20002802002d000145044010000b4100210241f701210103402001200346044020024138490d0305200028020020016a418a7e6a2d00002002410874722102200141016a21010c010b0b0b200241ff7d490d010b10000b20020b0b002000410120001b10090b2f01017f200028020820014904402001100920002802002000280204101c210220002001360208200020023602000b0bfc0801067f03400240200020046a2105200120046a210320022004460d002003410371450d00200520032d00003a0000200441016a21040c010b0b200220046b210602402005410371220745044003402006411049450440200020046a2203200120046a2205290200370200200341086a200541086a290200370200200441106a2104200641706a21060c010b0b027f2006410871450440200120046a2103200020046a0c010b200020046a2205200120046a2204290200370200200441086a2103200541086a0b21042006410471044020042003280200360200200341046a2103200441046a21040b20064102710440200420032f00003b0000200341026a2103200441026a21040b2006410171450d01200420032d00003a000020000f0b024020064120490d002007417f6a220741024b0d00024002400240024002400240200741016b0e020102000b2005200120046a220328020022073a0000200541016a200341016a2f00003b0000200041036a2108200220046b417d6a2106034020064111490d03200420086a2203200120046a220541046a2802002202410874200741187672360200200341046a200541086a2802002207410874200241187672360200200341086a2005410c6a28020022024108742007411876723602002003410c6a200541106a2802002207410874200241187672360200200441106a2104200641706a21060c000b000b2005200120046a220328020022073a0000200541016a200341016a2d00003a0000200041026a2108200220046b417e6a2106034020064112490d03200420086a2203200120046a220541046a2802002202411074200741107672360200200341046a200541086a2802002207411074200241107672360200200341086a2005410c6a28020022024110742007411076723602002003410c6a200541106a2802002207411074200241107672360200200441106a2104200641706a21060c000b000b2005200120046a28020022073a0000200041016a21082004417f7320026a2106034020064113490d03200420086a2203200120046a220541046a2802002202411874200741087672360200200341046a200541086a2802002207411874200241087672360200200341086a2005410c6a28020022024118742007410876723602002003410c6a200541106a2802002207411874200241087672360200200441106a2104200641706a21060c000b000b200120046a41036a2103200020046a41036a21050c020b200120046a41026a2103200020046a41026a21050c010b200120046a41016a2103200020046a41016a21050b20064110710440200520032d00003a00002005200328000136000120052003290005370005200520032f000d3b000d200520032d000f3a000f200541106a2105200341106a21030b2006410871044020052003290000370000200541086a2105200341086a21030b2006410471044020052003280000360000200541046a2105200341046a21030b20064102710440200520032f00003b0000200541026a2105200341026a21030b2006410171450d00200520032d00003a00000b20000b2101017f20011019220220012802044b044010000b2000200120011024200210250b2701017f230041206b22022400200241086a200020014114101710232100200241206a240020000b3f01027f2000280204220241016a220320002802084b047f20002003101b20002802040520020b20002802006a20013a00002000200028020441016a3602040b0f0020002001101b200020013602040b8d0301037f024020002001460d00200120006b20026b410020024101746b4d0440200020012002101c1a0c010b20002001734103712103027f024020002001490440200020030d021a410021030340200120036a2105200020036a2204410371450440200220036b210241002103034020024104490d04200320046a200320056a280200360200200341046a21032002417c6a21020c000b000b20022003460d04200420052d00003a0000200341016a21030c000b000b024020030d002001417f6a21040340200020026a22034103714504402001417c6a21032000417c6a2104034020024104490d03200220046a200220036a2802003602002002417c6a21020c000b000b2002450d042003417f6a200220046a2d00003a00002002417f6a21020c000b000b2001417f6a210103402002450d03200020026a417f6a200120026a2d00003a00002002417f6a21020c000b000b200320056a2101200320046a0b210303402002450d01200320012d00003a00002002417f6a2102200341016a2103200141016a21010c000b000b0b3501017f230041106b220041b0880436020c419c08200028020c41076a417871220036020041a008200036020041a4083f003602000b2e01017f200028020445044041000f0b4101210120002802002c0000417f4c047f20001024200010196a0520010b0b5b00027f027f41002000280204450d001a410020002802002c0000417f4a0d011a20002802002d0000220041bf014d04404100200041b801490d011a200041c97e6a0c010b4100200041f801490d001a200041897e6a0b41016a0b0b5b01027f2000027f0240200128020022054504400c010b200220036a200128020422014b0d0020012002490d00410020012003490d011a200220056a2104200120026b20032003417f461b0c010b41000b360204200020043602000b0b1301004180080b0c696e697400736574006765740a' +aa=bytes("init",'utf-8') +a1=fnv1_64(aa) +xx=to_binary(1020202) +# a21=HexBytes(a1) +a2=hex(a1) +a31=hexstr2bytes(a2) +a32=rlp_encode((a31,[])) +data1 = hexstr2bytes(data) +deploydata = rlp_encode((data1, a32)) +# a31=rlp_encode(a21) +a4=tostring_hex(a32) +print(a4) \ No newline at end of file diff --git a/client_sdk_python/utils/abi.py b/client_sdk_python/utils/abi.py index dd11fca..19433e1 100644 --- a/client_sdk_python/utils/abi.py +++ b/client_sdk_python/utils/abi.py @@ -4,14 +4,14 @@ import itertools import re -from eth_abi import ( +from client_sdk_python.packages.eth_abi import ( is_encodable as eth_abi_is_encodable, ) -from eth_abi.abi import ( +from client_sdk_python.packages.eth_abi.abi import ( collapse_type, process_type, ) -from eth_utils import ( +from client_sdk_python.packages.eth_utils import ( is_hex, is_list_like, to_bytes, @@ -45,7 +45,7 @@ def filter_by_name(name, contract_abi): for abi in contract_abi if ( - abi['type'] not in ('fallback', 'constructor') and + abi['type'] not in ('fallback', 'constructor','receive') and abi['name'] == name ) ] @@ -58,11 +58,17 @@ def get_abi_input_types(abi): return [arg['type'] for arg in abi['inputs']] -def get_abi_output_types(abi): +def get_abi_output_types(abi,vmtype): if abi['type'] == 'fallback': return [] else: - return [arg['type'] for arg in abi['outputs']] + if isinstance(abi['outputs'],dict): + if vmtype==1: + return abi['outputs'] + else : + return abi['outputs']['type'] + else : + return [arg['type'] for arg in abi['outputs']] def get_abi_input_names(abi): diff --git a/client_sdk_python/utils/blocks.py b/client_sdk_python/utils/blocks.py index c6c7843..ff36796 100644 --- a/client_sdk_python/utils/blocks.py +++ b/client_sdk_python/utils/blocks.py @@ -1,4 +1,4 @@ -from eth_utils import ( +from client_sdk_python.packages.eth_utils import ( is_bytes, is_hex, is_integer, diff --git a/client_sdk_python/utils/caching.py b/client_sdk_python/utils/caching.py index 3660571..05dc469 100644 --- a/client_sdk_python/utils/caching.py +++ b/client_sdk_python/utils/caching.py @@ -1,6 +1,6 @@ import hashlib -from eth_utils import ( +from client_sdk_python.packages.eth_utils import ( is_boolean, is_bytes, is_dict, diff --git a/client_sdk_python/utils/contracts.py b/client_sdk_python/utils/contracts.py index 2f3ec90..d3b17d4 100644 --- a/client_sdk_python/utils/contracts.py +++ b/client_sdk_python/utils/contracts.py @@ -1,12 +1,19 @@ import functools +import struct +import numpy as np +import rlp +from client_sdk_python.param_encode import ( + fnv1_64, + rlp_decode, +) -from eth_abi import ( +from client_sdk_python.packages.eth_abi import ( encode_abi as eth_abi_encode_abi, ) -from eth_abi.exceptions import ( +from client_sdk_python.packages.eth_abi.exceptions import ( EncodingError, ) -from eth_utils import ( +from client_sdk_python.packages.eth_utils import ( add_0x_prefix, encode_hex, function_abi_to_4byte_selector, @@ -34,6 +41,10 @@ ) from client_sdk_python.utils.encoding import ( to_hex, + hexstr2bytes, + tostring_hex, + stringtohex, + tobech32address, ) from client_sdk_python.utils.function_identifiers import ( FallbackFn, @@ -49,7 +60,13 @@ valmap, ) +from client_sdk_python.packages.platon_keys.utils import bech32,address +from client_sdk_python.packages.eth_utils import to_checksum_address +def find_wasm_abi(abi, fn_identifier=None): + for i in abi: + if i['name'] == fn_identifier: + return i def find_matching_event_abi(abi, event_name=None, argument_names=None): filters = [ @@ -126,46 +143,479 @@ def find_matching_fn_abi(abi, fn_identifier=None, args=None, kwargs=None): diagnosis=diagnosis, ) raise ValidationError(message) +def encodeuint(param): + arrlp = [] + if param: + temp1 = int(param) + while (temp1 % 0xff) or (temp1 & 0xff) : + temp = (hex(temp1 & 0xff)).replace('0x', '') + if len(temp) == 1: + temp = '0' + temp + arrlp.append(temp) + temp1 = temp1 >> 8 + arrlp.reverse() + else: + arrlp.append('00') + return arrlp + +def float_to_hex(f): + return hex(struct.unpack('>I', struct.pack('>f', f))[0]) + +def double_to_hex(d): + return hex(struct.unpack('>Q', struct.pack('>d', d))[0]) +def handlearrlp(arrlp,temp): + if isinstance(arrlp, list): + if isinstance(temp[0],list): + arrlp.append(tuple(temp)) + else: + arrlp.append(temp) + elif isinstance(arrlp, tuple): + arrlp = list(arrlp) + arrlp.append(temp) + arrlp = tuple(arrlp) + return arrlp +def tuplearrlp(arrlp,temp): + if isinstance(arrlp, list): + if isinstance(temp[0],list): + temp1=tuple(temp) + arrlp.append(temp1) + arrlp=tuple(arrlp) + else: + arrlp.append(temp) + arrlp=tuple(arrlp) + elif isinstance(arrlp, tuple): + arrlp = list(arrlp) + arrlp.append(temp) + arrlp = tuple(arrlp) + return arrlp +def encodeparameters(types,params,setabi=None): + arrlp = [] + if isinstance(params,set): + params = list(params) + for i in range(len(params)): + param = params[i] + type = types[i]['type'] + name = types[i]['name'] + if type == 'string': + arrlp.append(bytes(param,'utf-8')) + elif type.startswith('uint') and not type.endswith(']'): + temp=encodeuint(param) + arrlp.append(int(''.join(temp),16)) + elif type == 'bool': + arrlp.append(1 if param else 0) + elif type.startswith("int") and not type.endswith("]"): + temp1 = (param << 1) ^ (param >> 63) + temp = encodeuint(temp1) + arrlp.append(int(''.join(temp),16)) + elif type =='float': + temp1 =float_to_hex(param) + temp = hexstr2bytes(temp1) + arrlp.append(temp) + elif type =='double': + temp1 =double_to_hex(param) + temp = hexstr2bytes(temp1) + arrlp.append(temp) + elif type.endswith(']'): + vectype = type.split('[')[0] + temp=[] + vecLen = type[type.index('[') + 1:].split(']')[0] + if vectype == 'uint8' and vecLen =="": + arrlp.append(param) + else: + for i in param: + temp.append(encodeparameters([{'type':vectype,'name':''}],[i],setabi)[0]) + arrlp.append(temp) + elif type.startswith('list'): + i1 = type.index('<') + i2 = type.index('>') + itype = type[i1+1:i2] + temp=[] + for j in param: + temp.append(encodeparameters([{'type':itype,'name':''}], [j], setabi)[0]) + arrlp.append(temp) + elif type.startswith('map'): + i1=type.index('<') + i2=type.index(',') + i3=type.index('>') + ktype=type[i1+1:i2] + vtype=type[i2+1:i3] + temp = [] + for j in param: + kvalue=encodeparameters([{'type':ktype,'name':''}], [j[0]], setabi)[0] + vvalue=encodeparameters([{'type':vtype,'name':''}], [j[1]], setabi)[0] + temp.append([kvalue,vvalue]) + arrlp.append(temp) + elif type.startswith('pair'): + i1=type.index('<') + i2=type.index(',') + i3=type.index('>') + ktype=type[i1+1:i2] + vtype=type[i2+1:i3] + kvalue=encodeparameters([{'type':ktype, 'name':''}], [param[0]], setabi)[0] + vvalue=encodeparameters([{'type':vtype, 'name':''}], [param[1]], setabi)[0] + arrlp.append([kvalue,vvalue]) + + elif type.startswith('set'): + temp=[] + i1=type.index('<') + i2 = type.index('>') + stype=type[i1+1:i2] + for j in param: + temp.append(encodeparameters([{'type':stype,'name':''}],[j], setabi)[0]) + arrlp.append(temp) + elif type == 'struct': + temp=[] + structtype = [item for item in setabi if item['type'] == 'struct' and item['name'] == name] + if not structtype: + raise Exception('can not find struct in {} .'.format(name)) + else: + temp.append(encodeparameters(structtype[0]['inputs'], param, setabi)) + arrlp.append(temp) + + elif type=='FixedHash<20>': + temp=[] + if isinstance(param,str): + p1 = param[0:3] + p2 = param + elif isinstance(param,tuple): + p1 = param[0][0:3] + p2 = param[0] + if p1 == 'lax' or p1 == 'lat': + hrpgot, data1 = bech32.decode(p1, p2) + for i in data1: + temp1=hex(i).replace('0x', '') + if len(temp1)==1: + temp1='0'+temp1 + temp.append(temp1) + del temp1 + arrlp.append(temp) + elif type.startswith('FixedHash'): # 不是很确定,把'FixedHash'开头的类型理解为 ['0x33','0x6a'.'0x5e']这样的字节数组 + arrlp.append(param) + else : + structtype = [item for item in setabi if item['name'] == type] + if not structtype: + raise Exception('can not find struct through {} .'.format(type)) + else: + temp=encodeparameters(structtype[0]['inputs'], param, setabi) + arrlp.append(temp) + return arrlp + +#针对转化为uint的float和double,解码中以float a1=1.4为例,转化为uint32后为 a2='0x3fb33333' +# 转化为hex数组后为['3f','b3','33','33'],rlp编码后发到链上 +# 获得链上传回来的数据,对应float、double的是4字节和8字节的HexBytes,以a2作为代表 +# a3=struct.unpack('>f', HexBytes(a2)) 或者struct.unpack('>d', HexBytes(a2))[0] +# 1.399999976158142 或 1.4 +def decodeuint(param): + digit = 0 + if len(param) <= 1: + data1 = int(param[0], 16) + else: + for i in range(len(param)): + digit += int(param[i], 16) * (256 ** (len(param) - 1 - i)) #256 + data1 = digit + return data1 + + +def detail_decode_data(data_list): + detail_after = [] + for i in data_list: + if isinstance(i, list) and (detail_decode_data(i) not in detail_after): + detail_after.append(detail_decode_data(i)) + else: + if i not in detail_after: + str_i = to_hex(i) + if str_i[:2] == '0x': + detail_after.append(str_i[2:]) + else: + detail_after.append(str_i) + return detail_after + +def wasmdecode_abi(hrp, types, data, setabi=None): + if isinstance(data, HexBytes) or isinstance(data, bytes): + buf = detail_decode_data(rlp.decode(data)) + else: + buf = data + # print(f'wasmdecode_abi:{types,buf}') + type = types['type'] + name = types['name'] + if (not any(buf)) and ('int' in type): + buf = ['0'] + # data1 = buf + # if isinstance(data,HexBytes): + # decode_data = hexstr2bytes(to_hex(data)) + if type == 'string': + tem = [] + if isinstance(buf,list): + if not isinstance(buf[0],list): + for i in buf: + tem.append(bytes.decode(HexBytes(i))) + data1 = ''.join(tem) + else: + data1 = [wasmdecode_abi(hrp,{'type': type, 'name': ''}, j, setabi) for j in buf] + elif isinstance(buf, str): + data1 = bytes.decode(HexBytes(buf)) + elif isinstance(buf,tuple): + data1 = [wasmdecode_abi(hrp,{'type': type, 'name': ''}, j, setabi) for j in buf] + + elif type.startswith('uint') and not type.endswith(']'): + digit = 0 + if len(buf) <= 1: + data1 = int(buf[0],16) + else: + for i in range(len(buf)): + digit += int(buf[i],16)*(256**(len(buf)-1-i)) + data1 = digit + elif type == 'bool': + if not buf: + data1 = False + elif int(buf[0],16): + data1 = True + else: + data1 = False + elif type in ['int8', 'int16', 'int32', 'int64']: + if isinstance(buf, list): + buf = ''.join(buf) + temp = int(buf, 16) + data1 = (temp >> 1) ^ (temp & 1) * (-1) + elif type == 'float': + data1 = struct.unpack('>f', HexBytes(buf)) + elif type == 'double': + data1 = struct.unpack('>d', HexBytes(buf)) + elif type.endswith(']'): + lasti=type.rindex('[') + vectype=type[0:lasti] + if vectype == 'uint8': + data1 = buf + else: + data1 = [wasmdecode_abi(hrp,{'type':vectype,'name':''}, i, setabi) for i in buf] + + elif type.startswith('list'): + i1 = type.index('<') + i2 = type.index('>') + itype = type[i1 + 1:i2] + if isinstance(buf, tuple) and len(buf) <= 1: + buf =buf[0] + data1 = [wasmdecode_abi(hrp,{'type': itype, 'name': ''}, j, setabi) for j in buf] + elif type.startswith('map'): + i1 = type.index('<') + i2 = type.index(',') + i3 = type.index('>') + ktype = type[i1 + 1:i2] + vtype = type[i2 + 1:i3] + data1 = [] + for j in range(len(buf)): + if len(buf[j])<=1 and len(buf[j][0])>=2: + kvalue = wasmdecode_abi(hrp,{'type': ktype, 'name': ''}, buf[j][0][0], setabi) + vvalue = wasmdecode_abi(hrp,{'type': vtype, 'name': ''}, buf[j][0][1], setabi) + else: + kvalue = wasmdecode_abi(hrp,{'type': ktype, 'name': ''}, buf[j][0], setabi) + vvalue = wasmdecode_abi(hrp,{'type': vtype, 'name': ''}, buf[j][1], setabi) + data1.append([kvalue,vvalue]) + elif type.startswith('pair'): + i1=type.index('<') + i2=type.index(',') + i3=type.index('>') + ktype=type[i1+1:i2] + vtype=type[i2+1:i3] + data1 = [wasmdecode_abi(hrp,{'type': ktype, 'name': ''}, buf[0], setabi), + wasmdecode_abi(hrp,{'type': vtype, 'name': ''}, buf[1], setabi)] + elif type.startswith('set'): + i1=type.index('<') + i2 = type.index('>') + stype=type[i1+1:i2] + if isinstance(buf, tuple) and len(buf) <= 1: + buf = buf[0] + data1 = [ wasmdecode_abi(hrp,{'type':stype,'name':''},j, setabi) for j in buf] + data1=set(data1) + elif type == 'struct': + structtype = [item for item in setabi if item['type'] == 'struct' and item['name'] == name] + if not structtype: + raise Exception('can not find struct in {} .'.format(name)) + else: + data1 = [0 for x in range(len(structtype[0]['inputs']))] + for i in range(len(structtype[0]['inputs'])): + data1[i]=wasmdecode_abi(hrp,structtype[0]['inputs'][i], buf[i], setabi) + + elif type.startswith('FixedHash'): + data1 = '0x'+tostring_hex(buf) + if type.endswith('<20>'): + temp=[] + try : + temp=tobech32address(hrp,data1) + except: + raise ('wasmdecode error ! can not match FixedHash<20> type !' ) + finally: + data1 = temp + else: + structtype = [item for item in setabi if item['name'] == type] + if not structtype: + raise Exception('can not find struct through {} .'.format(type)) + else: + data1 = [0 for x in range(len(structtype[0]['inputs']))] + for i in range(len(structtype[0]['inputs'])): + data1[i]=wasmdecode_abi(hrp,structtype[0]['inputs'][i], buf[i], setabi) + + return data1 + +def encode_abi(web3, abi, arguments, vmtype, data=None, setabi=None): + arguments = list(arguments) + if vmtype == 1: + inputlength=len(abi['inputs']) + if inputlength == len(arguments): + if arguments: + arrinputs=abi['inputs'] + paramabi= encodeparameters(arrinputs, arguments, setabi) + else : + paramabi= [] + else : + raise Exception('The number of arguments is not matching the methods required number.' + 'You need to pass {} arguments.'.format(inputlength)) + magicnum=['00','61','73','6d'] + paramabi.insert(0, fnv1_64(bytes(abi['name'], 'utf8'))) + # print(f'paramabi:{paramabi}') + if abi['type']=='constructor': + if data: + data1 = bytes.fromhex(str(data, encoding='utf8')) + deploydata = rlp.encode([data1, rlp.encode(paramabi)]) + encodata = ''.join(magicnum) + deploydata.hex() + return '0x' + encodata + else : + return '0x' + rlp.encode(paramabi).hex() + else : + encodata = rlp.encode(paramabi).hex() + # print(f'encodata:{encodata}') + return '0x' + encodata -def encode_abi(web3, abi, arguments, data=None): - argument_types = get_abi_input_types(abi) + else: + argument_types = get_abi_input_types(abi) + for j in range(len(argument_types)): + if argument_types[j]: + if argument_types[j] == 'address': + hrpgot, data1 = bech32.decode(arguments[j][:3], arguments[j]) + addr = to_checksum_address(bytes(data1)) + arguments[j] = addr # .split(",") + elif argument_types[j] == 'address[]': + for i in range(len(arguments[j])): + hrpgot, data1 = bech32.decode(arguments[j][i][:3], arguments[j][i]) + addr = to_checksum_address(bytes(data1)) + arguments[j][i] = addr + + if not check_if_arguments_can_be_encoded(abi, arguments, {}): + raise TypeError( + "One or more arguments could not be encoded to the necessary " + "ABI type. Expected types are: {0}".format( + ', '.join(argument_types), + ) + ) - if not check_if_arguments_can_be_encoded(abi, arguments, {}): - raise TypeError( - "One or more arguments could not be encoded to the necessary " - "ABI type. Expected types are: {0}".format( - ', '.join(argument_types), + try: + normalizers = [ + abi_ens_resolver(web3), + abi_address_to_hex, + abi_bytes_to_bytes, + abi_string_to_text, + ] + normalized_arguments = map_abi_data( + normalizers, + argument_types, + arguments, + ) + encoded_arguments = eth_abi_encode_abi( + argument_types, + normalized_arguments, + ) + except EncodingError as e: + raise TypeError( + "One or more arguments could not be encoded to the necessary " + "ABI type: {0}".format(str(e)) ) - ) - try: - normalizers = [ - abi_ens_resolver(web3), - abi_address_to_hex, - abi_bytes_to_bytes, - abi_string_to_text, - ] - normalized_arguments = map_abi_data( - normalizers, - argument_types, - arguments, - ) - encoded_arguments = eth_abi_encode_abi( - argument_types, - normalized_arguments, - ) - except EncodingError as e: - raise TypeError( - "One or more arguments could not be encoded to the necessary " - "ABI type: {0}".format(str(e)) - ) + if data: + return to_hex(HexBytes(data) + encoded_arguments) + else: + return encode_hex(encoded_arguments) - if data: - return to_hex(HexBytes(data) + encoded_arguments) +def wasmevent_decode(hrp,types, data): + if isinstance(data, HexBytes) or isinstance(data, bytes): + bufs = detail_decode_data(rlp.decode(data)) else: - return encode_hex(encoded_arguments) - + bufs = data + data1 = [] + if (not any(bufs)) and ('int' in types): + bufs = ['0'] + if (not isinstance(bufs, tuple)) and (not isinstance(types, tuple)): + buf = bufs + type = types + if type == 'string': + tem = [] + if isinstance(buf, list): + if not isinstance(buf[0], list): + for i in buf: + tem.append(bytes.decode(HexBytes(i))) + data1 = ''.join(tem) + else: + data1 = [wasmevent_decode(hrp, {'type': type, 'name': ''}, j) for j in buf] + elif isinstance(buf, str): + data1 = bytes.decode(HexBytes(buf)) + elif isinstance(buf, tuple): + data1 = [wasmevent_decode(hrp, {'type': type, 'name': ''}, j) for j in buf] + elif type.startswith('uint') and not type.endswith(']'): + digit = 0 + if len(buf) <= 1: + data1 = int(buf[0],16) + else: + for i in range(len(buf)): + digit += int(buf[i],16)*(256**(len(buf)-1-i)) + data1 = digit + elif type == 'bool': + if not buf: + data1 = False + elif int(buf[0],16): + data1 = True + else: + data1 = False + elif type in ['int8', 'int16', 'int32', 'int64']: + if isinstance(buf, list): + buf = ''.join(buf) + temp = int(buf, 16) + data1 = (temp >> 1) ^ (temp & 1) * (-1) + elif type == 'float': + data1 = struct.unpack('>f', HexBytes(buf)) + elif type == 'double': + data1 = struct.unpack('>d', HexBytes(buf)) + elif type.endswith(']'): + lasti = type.rindex('[') + vectype = type[0:lasti] + if vectype == 'uint8': + data1 = buf + else: + data1 = [wasmevent_decode(hrp, {'type': vectype, 'name': ''}, i) for i in buf] + elif type.startswith('FixedHash'): + data1 = '0x'+tostring_hex(buf) + if type.endswith('<20>'): + temp=[] + try : + temp=tobech32address(hrp,data1) + except: + raise ('wasmdecode error ! can not match FixedHash<20> type !' ) + finally: + data1 = temp + else: + if len(bufs) != len(types): + if len(bufs[0]) == len(types): + data1 = [] + for i in range(len(bufs[0])): + buf = bufs[0][i] + type = types[i] + data1.append(wasmevent_decode(hrp,type, buf)) + else: + data1 = [] + for i in range(len(bufs)): + buf = bufs[i] + type = types[i] + data1.append(wasmevent_decode(hrp, type, buf)) + return data1 def prepare_transaction( address, @@ -173,6 +623,7 @@ def prepare_transaction( fn_identifier, contract_abi=None, fn_abi=None, + vmtype=None, transaction=None, fn_args=None, fn_kwargs=None): @@ -203,6 +654,7 @@ def prepare_transaction( fn_identifier, contract_abi, fn_abi, + vmtype, fn_args, fn_kwargs, ) @@ -214,6 +666,7 @@ def encode_transaction_data( fn_identifier, contract_abi=None, fn_abi=None, + vmtype=None, args=None, kwargs=None): if fn_identifier is FallbackFn: @@ -225,7 +678,7 @@ def encode_transaction_data( else: raise TypeError("Unsupported function identifier") - return add_0x_prefix(encode_abi(web3, fn_abi, fn_arguments, fn_selector)) + return add_0x_prefix(encode_abi(web3, fn_abi, fn_arguments, vmtype, fn_selector, contract_abi)) def get_fallback_function_info(contract_abi=None, fn_abi=None): diff --git a/client_sdk_python/utils/encoding.py b/client_sdk_python/utils/encoding.py index 6e05a2c..41fecfa 100644 --- a/client_sdk_python/utils/encoding.py +++ b/client_sdk_python/utils/encoding.py @@ -2,7 +2,7 @@ import json import re import rlp -from eth_utils import ( +from client_sdk_python.packages.eth_utils import ( add_0x_prefix, big_endian_to_int, decode_hex, @@ -15,6 +15,7 @@ is_list_like, remove_0x_prefix, to_hex, + is_address, ) from client_sdk_python.utils.abi import ( @@ -36,10 +37,10 @@ validate_abi_type, validate_abi_value, ) - +from client_sdk_python.packages.platon_keys.utils import bech32 def parse_str(raw_data): - data = str(raw_data, encoding="utf-8").replace('\\', '').replace('"[', '[').replace(']"', ']') + data = str(raw_data, encoding="utf-8") return json.loads(data) @@ -293,3 +294,85 @@ def to_4byte_hex(hex_or_str_or_bytes): ) hex_str = encode_hex(byte_str) return pad_hex(hex_str, size_of_4bytes) + +def hexstr2bytes(address: str): + pos = 0 + len_str = len(address) + if len_str % 2 != 0: + return None + len_str = round(len_str/2) + hexa = [] + for i in range(len_str): + s1 = address[pos:pos+2] + if s1 == '0x' or s1 == '0X': + pos +=2 + continue + sv = s1 + hexa.append(sv) + pos += 2 + return hexa + +def str2bytes(address: str): + pos = 0 + len_str = len(address) + if len_str % 2 != 0: + return None + len_str = round(len_str/2) + hexa = [] + for i in range(len_str): + s1 = address[pos:pos+2] + if s1 == '0x' or s1 == '0X': + pos +=2 + continue + sv = int(s1, 16) + hexa.append(sv) + pos += 2 + return hexa + +def encodeaddress(hrp, address): + program = str2bytes(address) + ret = bech32.encode(hrp,program) + return ret + + +def tobech32address(hrp, address): + if is_address(address): + return encodeaddress(hrp,address) + else: + return None + +def hexstr2bytes(address: str): + pos = 0 + len_str = len(address) + if len_str % 2 != 0: + return None + len_str = round(len_str/2) + hexa = [] + for i in range(len_str): + s1 = address[pos:pos+2] + if s1 == '0x' or s1 == '0X': + pos +=2 + continue + sv = s1 + hexa.append(sv) + pos += 2 + return hexa +def tostring_hex(arr:list): + arrhex='' + if arr: + for i in arr: + arrhex= arrhex+i + return arrhex + else : + return '' +def stringtohex(str1:bytes): + strhex=[] + if str1: + for i in str1: + temp = hex(i).replace('0x','') + if len(temp) == 1: + temp = '0'+temp + strhex = strhex+[temp] + del temp + return strhex + else: return [] \ No newline at end of file diff --git a/client_sdk_python/utils/ens.py b/client_sdk_python/utils/ens.py index 7ca53fe..f40d889 100644 --- a/client_sdk_python/utils/ens.py +++ b/client_sdk_python/utils/ens.py @@ -2,13 +2,13 @@ contextmanager, ) -from eth_utils import ( +from client_sdk_python.packages.eth_utils import ( is_0x_prefixed, is_hex, is_hex_address, ) -from ens import ENS +from client_sdk_python.packages.ens import ENS from client_sdk_python.exceptions import ( NameNotFound, ) diff --git a/client_sdk_python/utils/events.py b/client_sdk_python/utils/events.py index 0f66e05..a92c056 100644 --- a/client_sdk_python/utils/events.py +++ b/client_sdk_python/utils/events.py @@ -1,18 +1,19 @@ import itertools -from eth_abi import ( +from client_sdk_python.packages.eth_abi import ( decode_abi, decode_single, encode_single, ) -from eth_abi.abi import ( +from client_sdk_python.packages.eth_abi.abi import ( process_type, ) -from eth_utils import ( +from client_sdk_python.packages.eth_utils import ( encode_hex, event_abi_to_log_topic, is_list_like, to_tuple, + topic_decode, ) from client_sdk_python.datastructures import ( @@ -40,6 +41,8 @@ map_abi_data, normalize_event_input_types, ) +from client_sdk_python.utils.contracts import wasmevent_decode +from client_sdk_python.packages.platon_keys.utils.address import DEFAULTHRP def construct_event_topic_set(event_abi, arguments=None): @@ -145,7 +148,7 @@ def get_event_abi_types_for_decoding(event_inputs): yield input_abi['type'] -def get_event_data(event_abi, log_entry): +def get_event_data(event_abi, log_entry, vmtype=None, hrp=DEFAULTHRP): """ Given an event ABI and a log entry for that event, return the decoded event data @@ -154,7 +157,7 @@ def get_event_data(event_abi, log_entry): log_topics = log_entry['topics'] elif not log_entry['topics']: raise MismatchedABI("Expected non-anonymous event to have 1 or more topics") - elif event_abi_to_log_topic(event_abi) != log_entry['topics'][0]: + elif event_abi_to_log_topic(event_abi,vmtype) != log_entry['topics'][0]: raise MismatchedABI("The event signature did not match the provided ABI") else: log_topics = log_entry['topics'][1:] @@ -184,14 +187,6 @@ def get_event_data(event_abi, log_entry): "Invalid Event ABI: The following argument names are duplicated " "between event inputs: '{0}'".format(', '.join(duplicate_names)) ) - - decoded_log_data = decode_abi(log_data_types, log_data) - normalized_log_data = map_abi_data( - BASE_RETURN_NORMALIZERS, - log_data_types, - decoded_log_data - ) - decoded_topic_data = [ decode_single(topic_type, topic_data) for topic_type, topic_data @@ -202,6 +197,18 @@ def get_event_data(event_abi, log_entry): log_topic_types, decoded_topic_data ) + if vmtype: + normalized_log_data = wasmevent_decode(hrp,log_data_types, log_data) + if isinstance(normalized_topic_data[0],bytes): + if normalized_topic_data[0][0]==0: + normalized_topic_data = topic_decode(normalized_topic_data) + else: + decoded_log_data = decode_abi(log_data_types, log_data) + normalized_log_data = map_abi_data( + BASE_RETURN_NORMALIZERS, + log_data_types, + decoded_log_data + ) event_args = dict(itertools.chain( zip(log_topic_names, normalized_topic_data), diff --git a/client_sdk_python/utils/filters.py b/client_sdk_python/utils/filters.py index d2cfe7a..c6af917 100644 --- a/client_sdk_python/utils/filters.py +++ b/client_sdk_python/utils/filters.py @@ -1,6 +1,6 @@ import re -from eth_utils import ( +from client_sdk_python.packages.eth_utils import ( is_list_like, is_string, ) diff --git a/client_sdk_python/utils/formatters.py b/client_sdk_python/utils/formatters.py index 008bc7f..0c90b8d 100644 --- a/client_sdk_python/utils/formatters.py +++ b/client_sdk_python/utils/formatters.py @@ -3,7 +3,7 @@ Mapping, ) -from eth_utils import ( +from client_sdk_python.packages.eth_utils import ( is_dict, is_list_like, is_string, diff --git a/client_sdk_python/utils/module_testing/eth_module.py b/client_sdk_python/utils/module_testing/eth_module.py index 035d558..bbdf3a3 100644 --- a/client_sdk_python/utils/module_testing/eth_module.py +++ b/client_sdk_python/utils/module_testing/eth_module.py @@ -2,10 +2,10 @@ import pytest -from eth_abi import ( +from client_sdk_python.packages.eth_abi import ( decode_single, ) -from eth_utils import ( +from client_sdk_python.packages.eth_utils import ( is_boolean, is_bytes, is_checksum_address, diff --git a/client_sdk_python/utils/module_testing/net_module.py b/client_sdk_python/utils/module_testing/net_module.py index 71f7573..8c2445c 100644 --- a/client_sdk_python/utils/module_testing/net_module.py +++ b/client_sdk_python/utils/module_testing/net_module.py @@ -1,6 +1,6 @@ import pytest -from eth_utils import ( +from client_sdk_python.packages.eth_utils import ( is_boolean, is_integer, is_string, diff --git a/client_sdk_python/utils/module_testing/parity_module.py b/client_sdk_python/utils/module_testing/parity_module.py index 3599875..bc5d86a 100644 --- a/client_sdk_python/utils/module_testing/parity_module.py +++ b/client_sdk_python/utils/module_testing/parity_module.py @@ -1,6 +1,6 @@ import pytest -from eth_utils import ( +from client_sdk_python.packages.eth_utils import ( add_0x_prefix, ) diff --git a/client_sdk_python/utils/module_testing/personal_module.py b/client_sdk_python/utils/module_testing/personal_module.py index 9853399..eb6313b 100644 --- a/client_sdk_python/utils/module_testing/personal_module.py +++ b/client_sdk_python/utils/module_testing/personal_module.py @@ -1,4 +1,4 @@ -from eth_utils import ( +from client_sdk_python.packages.eth_utils import ( is_checksum_address, is_list_like, is_same_address, diff --git a/client_sdk_python/utils/module_testing/version_module.py b/client_sdk_python/utils/module_testing/version_module.py index c8c786e..1ce784f 100644 --- a/client_sdk_python/utils/module_testing/version_module.py +++ b/client_sdk_python/utils/module_testing/version_module.py @@ -1,4 +1,4 @@ -from eth_utils import ( +from client_sdk_python.packages.eth_utils import ( is_string, ) diff --git a/client_sdk_python/utils/normalizers.py b/client_sdk_python/utils/normalizers.py index fc77f7c..d565f59 100644 --- a/client_sdk_python/utils/normalizers.py +++ b/client_sdk_python/utils/normalizers.py @@ -6,14 +6,14 @@ import functools import json -import eth_abi -from eth_abi.abi import ( +import client_sdk_python.packages.eth_abi +from client_sdk_python.packages.eth_abi.abi import ( process_type, ) -from eth_utils import ( +from client_sdk_python.packages.eth_utils import ( to_checksum_address, ) -from eth_utils.address import ( +from client_sdk_python.packages.eth_utils.address import ( is_binary_address, ) from hexbytes import ( @@ -133,24 +133,24 @@ def abi_address_to_hex(abi_type, data): @curry def abi_ens_resolver(w3, abi_type, val): - if abi_type == 'address' and is_ens_name(val): + if abi_type == 'address': #and is_ens_name(val): if w3 is None: raise InvalidAddress( "Could not look up name %r because no web3" " connection available" % (val) ) - elif w3.ens is None: - raise InvalidAddress( - "Could not look up name %r because ENS is" - " set to None" % (val) - ) - elif int(w3.net.version) is not 1 and not isinstance(w3.ens, StaticENS): - raise InvalidAddress( - "Could not look up name %r because web3 is" - " not connected to mainnet" % (val) - ) + # elif w3.ens is None: + # raise InvalidAddress( + # "Could not look up name %r because ENS is" + # " set to None" % (val) + # ) + # elif int(w3.net.version) is not 1 and not isinstance(w3.ens, StaticENS): + # raise InvalidAddress( + # "Could not look up name %r because web3 is" + # " not connected to mainnet" % (val) + # ) else: - return (abi_type, validate_name_has_address(w3.ens, val)) + return (abi_type, val) else: return (abi_type, val) @@ -160,8 +160,8 @@ def abi_ens_resolver(w3, abi_type, val): ] -if LooseVersion(eth_abi.__version__) < LooseVersion("2"): - BASE_RETURN_NORMALIZERS.append(decode_abi_strings) +# if LooseVersion(eth_abi.__version__) < LooseVersion("2"): +BASE_RETURN_NORMALIZERS.append(decode_abi_strings) # @@ -176,14 +176,16 @@ def normalize_abi(abi): return abi -def normalize_address(ens, address): - if address: - if is_ens_name(address): - validate_name_has_address(ens, address) - else: - validate_address(address) +def normalize_address(address): + # if address: + # if is_ens_name(address): + # validate_name_has_address(ens, address) + # else: + # validate_address(address) return address +def normalize_vmtype(vmtype): + return vmtype def normalize_bytecode(bytecode): if bytecode: diff --git a/client_sdk_python/utils/rpc_abi.py b/client_sdk_python/utils/rpc_abi.py index 72d9745..d652c97 100644 --- a/client_sdk_python/utils/rpc_abi.py +++ b/client_sdk_python/utils/rpc_abi.py @@ -1,4 +1,4 @@ -from eth_utils import ( +from client_sdk_python.packages.eth_utils import ( to_dict, ) diff --git a/client_sdk_python/utils/transactions.py b/client_sdk_python/utils/transactions.py index 9a9506d..3d9a81f 100644 --- a/client_sdk_python/utils/transactions.py +++ b/client_sdk_python/utils/transactions.py @@ -1,3 +1,4 @@ +import json import math from client_sdk_python.utils.threads import ( @@ -8,10 +9,10 @@ curry, merge, ) - +from client_sdk_python.error_code import ERROR_INFO from hexbytes import HexBytes -from platon_keys.datatypes import PrivateKey +from client_sdk_python.packages.platon_keys.datatypes import PrivateKey VALID_TRANSACTION_PARAMS = [ 'from', @@ -55,9 +56,19 @@ def send_obj_transaction(obj, data, to_address, pri_key, transaction_cfg: dict): else: transaction_dict["nonce"] = transaction_cfg["nonce"] if transaction_cfg.get("gas", None) is None: - from_address = obj.web3.pubkey_to_address(PrivateKey(bytes.fromhex(pri_key)).public_key) - transaction_data = {"to": to_address, "data": data, "from": from_address} - transaction_dict["gas"] = obj.web3.platon.estimateGas(transaction_data) + if obj.need_quota_gas: + transaction_dict["gas"] = 9424776 + else: + from_address = obj.web3.pubkey_to_address(PrivateKey(bytes.fromhex(pri_key)).public_key) + transaction_data = {"to": to_address, "data": data, "from": from_address} + try: + transaction_dict["gas"] = obj.web3.platon.estimateGas(transaction_data) + except Exception as e: + res = str(e).replace('\'', '\"') + if '-32000' in res: + raise e + res_json = json.loads(res) + return res_json.get('data').get('code') else: transaction_dict["gas"] = transaction_cfg["gas"] transaction_dict["chainId"] = obj.web3.chainId @@ -71,8 +82,10 @@ def send_obj_transaction(obj, data, to_address, pri_key, transaction_cfg: dict): signed_data = signed_transaction_dict.rawTransaction tx_hash = HexBytes(obj.web3.platon.sendRawTransaction(signed_data)).hex() if obj.need_analyze: - return obj.web3.platon.analyzeReceiptByHash(tx_hash) - return tx_hash + code = obj.web3.platon.analyzeReceiptByHash(tx_hash) + code_info = ERROR_INFO.get(code, 'Unknown code info') + return {'hash': tx_hash, 'code': code, 'code_info': code_info} + return {'hash': tx_hash, 'code': '', 'code_info': ''} @curry def fill_nonce(web3, transaction): diff --git a/client_sdk_python/utils/validation.py b/client_sdk_python/utils/validation.py index 6c2a39b..36ca58a 100644 --- a/client_sdk_python/utils/validation.py +++ b/client_sdk_python/utils/validation.py @@ -1,6 +1,6 @@ import itertools -from eth_utils import ( +from client_sdk_python.packages.eth_utils import ( function_abi_to_4byte_selector, is_0x_prefixed, is_binary_address, @@ -13,7 +13,7 @@ is_list_like, is_string, ) -from eth_utils.hexadecimal import ( +from client_sdk_python.packages.eth_utils.hexadecimal import ( encode_hex, ) diff --git a/client_sdk_python/wasmcontract.py b/client_sdk_python/wasmcontract.py new file mode 100644 index 0000000..251374c --- /dev/null +++ b/client_sdk_python/wasmcontract.py @@ -0,0 +1,1591 @@ +"""Interaction with smart contracts over Web3 connector. + +""" +import copy +import functools +import itertools + +from client_sdk_python.packages.eth_abi import ( + decode_abi, +) +from client_sdk_python.packages.eth_abi.exceptions import ( + DecodingError, +) +from client_sdk_python.packages.eth_utils import ( + add_0x_prefix, + encode_hex, + function_abi_to_4byte_selector, + is_text, + to_tuple, +) +from hexbytes import ( + HexBytes, +) + +from client_sdk_python.exceptions import ( + BadFunctionCallOutput, + BlockNumberOutofRange, + FallbackNotFound, + MismatchedABI, + NoABIEventsFound, + NoABIFunctionsFound, +) +from client_sdk_python.utils.abi import ( + abi_to_signature, + check_if_arguments_can_be_encoded, + fallback_func_abi_exists, + filter_by_type, + get_abi_output_types, + get_constructor_abi, + map_abi_data, + merge_args_and_kwargs, +) +from client_sdk_python.utils.blocks import ( + is_hex_encoded_block_hash, +) +from client_sdk_python.utils.contracts import ( + encode_abi, + find_matching_event_abi, + find_matching_fn_abi, + get_function_info, + prepare_transaction, +) +from client_sdk_python.utils.datatypes import ( + PropertyCheckingFactory, +) +from client_sdk_python.utils.decorators import ( + combomethod, + deprecated_for, +) +from client_sdk_python.utils.empty import ( + empty, +) +from client_sdk_python.utils.encoding import ( + to_4byte_hex, + to_hex, + tobech32address, +) +from client_sdk_python.utils.events import ( + get_event_data, +) +from client_sdk_python.utils.filters import ( + construct_event_filter_params, +) +from client_sdk_python.utils.function_identifiers import ( + FallbackFn, +) +from client_sdk_python.utils.normalizers import ( + BASE_RETURN_NORMALIZERS, + normalize_abi, + normalize_address, + normalize_bytecode, + normalize_vmtype, +) +from client_sdk_python.utils.toolz import ( + compose, + partial, +) +from client_sdk_python.utils.transactions import ( + fill_transaction_defaults, +) + +from client_sdk_python.packages.platon_keys.utils import bech32 + +DEPRECATED_SIGNATURE_MESSAGE = ( + "The constructor signature for the `Contract` object has changed. " + "Please update your code to reflect the updated function signature: " + "'Contract(address)'. To construct contract classes use the " + "'Contract.factory(...)' class method." +) + +ACCEPTABLE_EMPTY_STRINGS = ["0x", b"0x", "", b""] + + +class ContractFunctions: + """Class containing contract function objects + """ + + def __init__(self, abi, web3, address=None): + if abi: + self.abi = abi + self._functions = filter_by_type('function', self.abi) + for func in self._functions: + setattr( + self, + func['name'], + ContractFunction.factory( + func['name'], + web3=web3, + contract_abi=self.abi, + address=address, + function_identifier=func['name'])) + + def __iter__(self): + if not hasattr(self, '_functions') or not self._functions: + return + + for func in self._functions: + yield func['name'] + + def __getattr__(self, function_name): + if '_functions' not in self.__dict__: + raise NoABIFunctionsFound( + "The abi for this contract contains no function definitions. ", + "Are you sure you provided the correct contract abi?" + ) + elif function_name not in self.__dict__['_functions']: + raise MismatchedABI( + "The function '{}' was not found in this contract's abi. ".format(function_name), + "Are you sure you provided the correct contract abi?" + ) + else: + return super().__getattribute__(function_name) + + def __getitem__(self, function_name): + return getattr(self, function_name) + + +class ContractEvents: + """Class containing contract event objects + """ + + def __init__(self, abi, web3, address=None): + if abi: + self.abi = abi + self._events = filter_by_type('event', self.abi) + for event in self._events: + setattr( + self, + event['name'], + ContractEvent.factory( + event['name'], + web3=web3, + contract_abi=self.abi, + address=address, + event_name=event['name'])) + + def __getattr__(self, event_name): + if '_events' not in self.__dict__: + raise NoABIEventsFound( + "The abi for this contract contains no event definitions. ", + "Are you sure you provided the correct contract abi?" + ) + elif event_name not in self.__dict__['_events']: + raise MismatchedABI( + "The event '{}' was not found in this contract's abi. ".format(event_name), + "Are you sure you provided the correct contract abi?" + ) + else: + return super().__getattribute__(event_name) + + def __getitem__(self, event_name): + return getattr(self, event_name) + + +class WasmContract: + """Base class for Contract proxy classes. + + First you need to create your Contract classes using + :meth:`web3.eth.Eth.contract` that takes compiled Solidity contract + ABI definitions as input. The created class object will be a subclass of + this base class. + + After you have your Contract proxy class created you can interact with + smart contracts + + * Create a Contract proxy object for an existing deployed smart contract by + its address using :meth:`__init__` + + * Deploy a new smart contract using :py:meth:`Contract.deploy` + """ + + # set during class construction + web3 = None + + # instance level properties + address = None + + # class properties (overridable at instance level) + abi = None + + asm = None + ast = None + + bytecode = None + bytecode_runtime = None + clone_bin = None + + functions = None + events = None + + dev_doc = None + interface = None + metadata = None + opcodes = None + src_map = None + src_map_runtime = None + user_doc = None + vmtype= None + + def __init__(self, address=None): + """Create a new smart contract proxy object. + + :param address: Contract address as 0x hex string + """ + if self.web3 is None: + raise AttributeError( + 'The `Contract` class has not been initialized. Please use the ' + '`web3.contract` interface to create your contract class.' + ) + + if address: + self.address = normalize_address(address) + + if not self.address: + raise TypeError("The address argument is required to instantiate a contract.") + + self.functions = ContractFunctions(self.abi, self.web3, self.address) + self.events = ContractEvents(self.abi, self.web3, self.address) + self.fallback = WasmContract.get_fallback_function(self.abi, self.web3, self.address) + + def wasm_type(self,abi_data): + for i in range(len(abi_data)): + if abi_data[i]['type']=='Action': + abi_data[i]['type']='function' + if abi_data[i]['type']=='Event': + abi_data[i]['type'] = 'event' + abi_data[i]['anonymous'] = False + if len(abi_data[i]['input']) > 0: + for j in range(len(abi_data[i]['input'])): + abi_data[i]['input'][j]['indexed'] = ((j+1) <= abi_data[i]['topic']) + if abi_data[i]['type']=='struct': + abi_data[i]['inputs'] = abi_data[i].pop('fields') + if len(abi_data[i]['baseclass'])>0: + for j in range(len(abi_data[i]['baseclass'])): + abi_data[i]['inputs'].insert(j,{'name':abi_data[i]['baseclass'][j],'type':'struct'}) + else : + abi_data[i]['inputs'].insert(0, {'name': abi_data[i]['baseclass'], 'type': 'struct'}) + del abi_data[i]['baseclass'] + if abi_data[i]['name']== 'init': + abi_data[i]['type']='constructor' + if 'input' in abi_data[i]: + abi_data[i]['inputs'] = abi_data[i].pop('input') + if 'output' in abi_data[i]: + abi_data[i]['outputs'] = {'name':"",'type':abi_data[i]['output']} + del abi_data[i]['output'] + return abi_data + + @classmethod + def wasmfactory(cls, web3, class_name=None, **kwargs): + + kwargs['web3'] = web3 + if 'vmtype' in kwargs: + if kwargs['vmtype'] == 1: + normalizers = { + 'abi': normalize_abi, + 'address': normalize_address, + 'vmtype':normalize_vmtype, + 'bytecode': normalize_bytecode, + 'bytecode_runtime': normalize_bytecode, + } + contract = PropertyCheckingFactory( + class_name or cls.__name__, + (cls,), + kwargs, + normalizers=normalizers) + setattr(contract, 'functions', ContractFunctions(contract.abi, contract.web3)) + setattr(contract, 'events', ContractEvents(contract.abi, contract.web3)) + setattr(contract, 'fallback', WasmContract.get_fallback_function(contract.abi, contract.web3)) + + return contract + + # + # Contract Methods + # + @classmethod + @deprecated_for("contract.constructor.transact") + def deploy(cls, transaction=None, args=None, kwargs=None): + """ + Deploys the contract on a blockchain. + + Example: + + .. code-block:: python + + >>> MyContract.deploy( + transaction={ + 'from': web3.eth.accounts[1], + 'value': 12345, + }, + args=('DGD', 18), + ) + '0x5c504ed432cb51138bcf09aa5e8a410dd4a1e204ef84bfed1be16dfba1b22060' + + :param transaction: Transaction parameters for the deployment + transaction as a dict + + :param args: The contract constructor arguments as positional arguments + :param kwargs: The contract constructor arguments as keyword arguments + + :return: hexadecimal transaction hash of the deployment transaction + """ + if transaction is None: + deploy_transaction = {} + else: + deploy_transaction = dict(**transaction) + + if not cls.bytecode: + raise ValueError( + "Cannot deploy a contract that does not have 'bytecode' associated " + "with it" + ) + + if 'data' in deploy_transaction: + raise ValueError( + "Cannot specify `data` for contract deployment" + ) + + if 'to' in deploy_transaction: + raise ValueError( + "Cannot specify `to` for contract deployment" + ) + + deploy_transaction['data'] = cls._encode_constructor_data(args, kwargs) + + txn_hash = cls.web3.eth.sendTransaction(deploy_transaction) + return txn_hash + + @classmethod + def constructor(cls, *args, **kwargs): + """ + :param args: The contract constructor arguments as positional arguments + :param kwargs: The contract constructor arguments as keyword arguments + :return: a contract constructor object + """ + if cls.bytecode is None: + raise ValueError( + "Cannot call constructor on a contract that does not have 'bytecode' associated " + "with it" + ) + return ContractConstructor(cls.web3, + cls.abi, + cls.bytecode, + cls.vmtype, + *args, + **kwargs) + + # Public API + # + @combomethod + def encodeABI(cls, fn_name, args=None, kwargs=None, data=None): + """ + Encodes the arguments using the Ethereum ABI for the contract function + that matches the given name and arguments.. + + :param data: defaults to function selector + """ + fn_abi, fn_selector, fn_arguments = get_function_info( + fn_name, contract_abi=cls.abi, args=args, kwargs=kwargs, + ) + + if data is None: + data = fn_selector + + return encode_abi(cls.web3, fn_abi, fn_arguments, cls.vmtype, data, cls.abi) + + @combomethod + @deprecated_for("contract.events..createFilter") + def eventFilter(self, event_name, filter_params={}): + """ + Create filter object that tracks events emitted by this contract. + :param event_name: the name of the event to track + :param filter_params: other parameters to limit the events + """ + filter_meta_params = dict(filter_params) + argument_filters = filter_meta_params.pop('filter', {}) + + argument_filter_names = list(argument_filters.keys()) + event_abi = self._find_matching_event_abi( + event_name, + argument_filter_names, + ) + + data_filter_set, event_filter_params = construct_event_filter_params( + event_abi, + contract_address=self.address, + argument_filters=argument_filters, + **filter_meta_params + ) + + log_data_extract_fn = functools.partial(get_event_data, event_abi) + + log_filter = self.web3.eth.filter(event_filter_params) + + log_filter.set_data_filters(data_filter_set) + log_filter.log_entry_formatter = log_data_extract_fn + log_filter.filter_params = event_filter_params + + return log_filter + + @combomethod + @deprecated_for("contract.functions..estimateGas") + def estimateGas(self, transaction=None): + """ + Estimate the gas for a call + """ + if transaction is None: + estimate_transaction = {} + else: + estimate_transaction = dict(**transaction) + + if 'data' in estimate_transaction: + raise ValueError("Cannot set data in call transaction") + if 'to' in estimate_transaction: + raise ValueError("Cannot set to in call transaction") + + if self.address: + estimate_transaction.setdefault('to', self.address) + if self.web3.eth.defaultAccount is not empty: + estimate_transaction.setdefault('from', self.web3.eth.defaultAccount) + + if 'to' not in estimate_transaction: + if isinstance(self, type): + raise ValueError( + "When using `Contract.estimateGas` from a contract factory " + "you must provide a `to` address with the transaction" + ) + else: + raise ValueError( + "Please ensure that this contract instance has an address." + ) + + contract = self + + class Caller: + def __getattr__(self, function_name): + callable_fn = functools.partial( + estimate_gas_for_function, + contract.address, + contract.web3, + function_name, + estimate_transaction, + contract.abi, + None, + ) + return callable_fn + + return Caller() + + @combomethod + @deprecated_for("contract...call") + def call(self, transaction=None): + """ + Execute a contract function call using the `platon_call` interface. + + This method prepares a ``Caller`` object that exposes the contract + functions and public variables as callable Python functions. + + Reading a public ``owner`` address variable example: + + .. code-block:: python + + ContractFactory = w3.eth.contract( + abi=wallet_contract_definition["abi"] + ) + + # Not a real contract address + contract = ContractFactory("0x2f70d3d26829e412A602E83FE8EeBF80255AEeA5") + + # Read "owner" public variable + addr = contract.functions.owner().call() + + :param transaction: Dictionary of transaction info for web3 interface + :return: ``Caller`` object that has contract public functions + and variables exposed as Python methods + """ + if transaction is None: + call_transaction = {} + else: + call_transaction = dict(**transaction) + + if 'data' in call_transaction: + raise ValueError("Cannot set data in call transaction") + + if self.address: + call_transaction.setdefault('to', self.address) + if self.web3.eth.defaultAccount is not empty: + call_transaction.setdefault('from', self.web3.eth.defaultAccount) + + if 'to' not in call_transaction: + if isinstance(self, type): + raise ValueError( + "When using `Contract.call` from a contract factory you " + "must provide a `to` address with the transaction" + ) + else: + raise ValueError( + "Please ensure that this contract instance has an address." + ) + + contract = self + + class Caller: + def __getattr__(self, function_name): + callable_fn = functools.partial( + call_contract_function, + contract.web3, + contract.address, + contract._return_data_normalizers, + function_name, + call_transaction, + 'latest', + contract.abi, + None, + ) + return callable_fn + + return Caller() + + @combomethod + @deprecated_for("contract...transact") + def transact(self, transaction=None): + """ + Execute a contract function call using the `platon_sendTransaction` + interface. + + You should specify the account that pays the gas for this transaction + in `transaction`. If no account is specified the coinbase account of + web3 interface is used. + + Example: + + .. code-block:: python + + # Assume we have a Wallet contract with the following methods. + # * Wallet.deposit() # deposits to `msg.sender` + # * Wallet.deposit(address to) # deposits to the account indicated + # by the `to` parameter. + # * Wallet.withdraw(address amount) + + >>> wallet = Wallet(address='0xDc3A9Db694BCdd55EBaE4A89B22aC6D12b3F0c24') + # Deposit to the `web3.eth.coinbase` account. + >>> wallet.functions.deposit().transact({'value': 12345}) + '0x5c504ed432cb51138bcf09aa5e8a410dd4a1e204ef84bfed1be16dfba1b22060' + # Deposit to some other account using funds from `web3.eth.coinbase`. + >>> wallet.functions.deposit(web3.eth.accounts[1]).transact({'value': 54321}) + '0xe122ba26d25a93911e241232d3ba7c76f5a6bfe9f8038b66b198977115fb1ddf' + # Withdraw 12345 wei. + >>> wallet.functions.withdraw(12345).transact() + + The new public transaction will be created. Transaction receipt will + be available once the transaction has been mined. + + :param transaction: Dictionary of transaction info for web3 interface. + Variables include ``from``, ``gas``, ``value``, ``gasPrice``, ``nonce``. + + :return: ``Transactor`` object that has contract + public functions exposed as Python methods. + Calling these methods will execute a transaction against the contract. + + """ + if transaction is None: + transact_transaction = {} + else: + transact_transaction = dict(**transaction) + + if 'data' in transact_transaction: + raise ValueError("Cannot set data in call transaction") + + if self.address is not None: + transact_transaction.setdefault('to', self.address) + if self.web3.eth.defaultAccount is not empty: + transact_transaction.setdefault('from', self.web3.eth.defaultAccount) + + if 'to' not in transact_transaction: + if isinstance(self, type): + raise ValueError( + "When using `Contract.transact` from a contract factory you " + "must provide a `to` address with the transaction" + ) + else: + raise ValueError( + "Please ensure that this contract instance has an address." + ) + + contract = self + + class Transactor: + def __getattr__(self, function_name): + callable_fn = functools.partial( + transact_with_contract_function, + contract.address, + contract.web3, + function_name, + transact_transaction, + contract.abi, + None, + ) + return callable_fn + + return Transactor() + + @combomethod + @deprecated_for("contract...buildTransaction") + def buildTransaction(self, transaction=None): + """ + Build the transaction dictionary without sending + """ + if transaction is None: + built_transaction = {} + else: + built_transaction = dict(**transaction) + + if 'data' in built_transaction: + raise ValueError("Cannot set data in call buildTransaction") + + if isinstance(self, type) and 'to' not in built_transaction: + raise ValueError( + "When using `Contract.buildTransaction` from a contract factory " + "you must provide a `to` address with the transaction" + ) + if not isinstance(self, type) and 'to' in built_transaction: + raise ValueError("Cannot set to in call buildTransaction") + + if self.address: + built_transaction.setdefault('to', self.address) + + if 'to' not in built_transaction: + raise ValueError( + "Please ensure that this contract instance has an address." + ) + + contract = self + + class Caller: + def __getattr__(self, function_name): + callable_fn = functools.partial( + build_transaction_for_function, + contract.address, + contract.web3, + function_name, + built_transaction, + contract.abi, + None, + ) + return callable_fn + + return Caller() + + @combomethod + def all_functions(self): + return find_functions_by_identifier( + self.abi, self.web3, self.address, lambda _: True + ) + + @combomethod + def get_function_by_signature(self, signature): + if ' ' in signature: + raise ValueError( + 'Function signature should not contain any spaces. ' + 'Found spaces in input: %s' % signature + ) + + def callable_check(fn_abi): + return abi_to_signature(fn_abi) == signature + + fns = find_functions_by_identifier(self.abi, self.web3, self.address, callable_check) + return get_function_by_identifier(fns, 'signature') + + @combomethod + def find_functions_by_name(self, fn_name): + def callable_check(fn_abi): + return fn_abi['name'] == fn_name + + return find_functions_by_identifier( + self.abi, self.web3, self.address, callable_check + ) + + @combomethod + def get_function_by_name(self, fn_name): + fns = self.find_functions_by_name(fn_name) + return get_function_by_identifier(fns, 'name') + + @combomethod + def get_function_by_selector(self, selector): + def callable_check(fn_abi): + return encode_hex(function_abi_to_4byte_selector(fn_abi)) == to_4byte_hex(selector) + + fns = find_functions_by_identifier(self.abi, self.web3, self.address, callable_check) + return get_function_by_identifier(fns, 'selector') + + @combomethod + def decode_function_input(self, data): + data = HexBytes(data) + selector, params = data[:4], data[4:] + func = self.get_function_by_selector(selector) + names = [x['name'] for x in func.abi['inputs']] + types = [x['type'] for x in func.abi['inputs']] + decoded = decode_abi(types, params) + normalized = map_abi_data(BASE_RETURN_NORMALIZERS, types, decoded) + return func, dict(zip(names, normalized)) + + @combomethod + def find_functions_by_args(self, *args): + def callable_check(fn_abi): + return check_if_arguments_can_be_encoded(fn_abi, args=args, kwargs={}) + + return find_functions_by_identifier( + self.abi, self.web3, self.address, callable_check + ) + + @combomethod + def get_function_by_args(self, *args): + fns = self.find_functions_by_args(*args) + return get_function_by_identifier(fns, 'args') + + # + # Private Helpers + # + _return_data_normalizers = tuple() + + @classmethod + def _prepare_transaction(cls, + fn_name, + fn_args=None, + fn_kwargs=None, + transaction=None): + + return prepare_transaction( + cls.address, + cls.web3, + fn_identifier=fn_name, + contract_abi=cls.abi, + transaction=transaction, + fn_args=fn_args, + fn_kwargs=fn_kwargs, + ) + + @classmethod + def _find_matching_fn_abi(cls, fn_identifier=None, args=None, kwargs=None): + return find_matching_fn_abi(cls.abi, + fn_identifier=fn_identifier, + args=args, + kwargs=kwargs) + + @classmethod + def _find_matching_event_abi(cls, event_name=None, argument_names=None): + return find_matching_event_abi( + abi=cls.abi, + event_name=event_name, + argument_names=argument_names) + + @staticmethod + def get_fallback_function(abi, web3, address=None): + if abi and fallback_func_abi_exists(abi): + return ContractFunction.factory( + 'fallback', + web3=web3, + contract_abi=abi, + address=address, + function_identifier=FallbackFn)() + + return NonExistentFallbackFunction() + + @combomethod + def _encode_constructor_data(cls, args=None, kwargs=None): + constructor_abi = get_constructor_abi(cls.abi) + + if constructor_abi: + if args is None: + args = tuple() + if kwargs is None: + kwargs = {} + + arguments = merge_args_and_kwargs(constructor_abi, args, kwargs) + + deploy_data = add_0x_prefix( + encode_abi(cls.web3, constructor_abi, arguments, cls.vmtype, cls.bytecode, cls.abi) + ) + else: + deploy_data = to_hex(cls.bytecode) + + return deploy_data + + +def mk_collision_prop(fn_name): + def collision_fn(): + msg = "Namespace collision for function name {0} with ConciseContract API.".format(fn_name) + raise AttributeError(msg) + collision_fn.__name__ = fn_name + return collision_fn + + +class ContractConstructor: + """ + Class for contract constructor API. + """ + def __init__(self, web3, abi, bytecode,vmtype, *args, **kwargs): + self.web3 = web3 + self.abi = abi + self.bytecode = bytecode + self.vmtype = vmtype + self.data_in_transaction = self._encode_data_in_transaction(*args, **kwargs) + + @combomethod + def _encode_data_in_transaction(self, *args, **kwargs): + constructor_abi = get_constructor_abi(self.abi) + + if constructor_abi: + if not args: + args = tuple() + if not kwargs: + kwargs = {} + + arguments = merge_args_and_kwargs(constructor_abi, args, kwargs) + data = add_0x_prefix( + encode_abi(self.web3, constructor_abi, arguments, self.vmtype, self.bytecode, self.abi) + ) + else: + data = to_hex(self.bytecode) + + return data + + @combomethod + def estimateGas(self, transaction=None): + if transaction is None: + estimate_gas_transaction = {} + else: + estimate_gas_transaction = dict(**transaction) + self.check_forbidden_keys_in_transaction(estimate_gas_transaction, + ["data", "to"]) + + if self.web3.eth.defaultAccount is not empty: + estimate_gas_transaction.setdefault('from', self.web3.eth.defaultAccount) + + estimate_gas_transaction['data'] = self.data_in_transaction + + return self.web3.eth.estimateGas(estimate_gas_transaction) + + @combomethod + def transact(self, transaction=None): + if transaction is None: + transact_transaction = {} + else: + transact_transaction = dict(**transaction) + self.check_forbidden_keys_in_transaction(transact_transaction, + ["data", "to"]) + + if self.web3.eth.defaultAccount is not empty: + transact_transaction.setdefault('from', self.web3.eth.defaultAccount) + + transact_transaction['data'] = self.data_in_transaction + + # TODO: handle asynchronous contract creation + return self.web3.eth.sendTransaction(transact_transaction) + + @combomethod + def buildTransaction(self, transaction=None): + """ + Build the transaction dictionary without sending + """ + + if transaction is None: + built_transaction = {} + else: + built_transaction = dict(**transaction) + self.check_forbidden_keys_in_transaction(built_transaction, + ["data", "to"]) + + if self.web3.eth.defaultAccount is not empty: + built_transaction.setdefault('from', self.web3.eth.defaultAccount) + + built_transaction['data'] = self.data_in_transaction + built_transaction['to'] = b'' + return fill_transaction_defaults(self.web3, built_transaction) + + @staticmethod + def check_forbidden_keys_in_transaction(transaction, forbidden_keys=None): + keys_found = set(transaction.keys()) & set(forbidden_keys) + if keys_found: + raise ValueError("Cannot set {} in transaction".format(', '.join(keys_found))) + + +class ConciseMethod: + ALLOWED_MODIFIERS = {'call', 'estimateGas', 'transact', 'buildTransaction'} + + def __init__(self, function, normalizers=None): + self._function = function + self._function._return_data_normalizers = normalizers + + def __call__(self, *args, **kwargs): + return self.__prepared_function(*args, **kwargs) + + def __prepared_function(self, *args, **kwargs): + if not kwargs: + modifier, modifier_dict = 'call', {} + elif len(kwargs) == 1: + modifier, modifier_dict = kwargs.popitem() + if modifier not in self.ALLOWED_MODIFIERS: + raise TypeError( + "The only allowed keyword arguments are: %s" % self.ALLOWED_MODIFIERS) + else: + raise TypeError("Use up to one keyword argument, one of: %s" % self.ALLOWED_MODIFIERS) + + return getattr(self._function(*args), modifier)(modifier_dict) + + +class ConciseContract: + ''' + An alternative Contract Factory which invokes all methods as `call()`, + unless you add a keyword argument. The keyword argument assigns the prep method. + + This call + + > contract.withdraw(amount, transact={'from': eth.accounts[1], 'gas': 100000, ...}) + + is equivalent to this call in the classic contract: + + > contract.functions.withdraw(amount).transact({'from': eth.accounts[1], 'gas': 100000, ...}) + ''' + def __init__(self, classic_contract, method_class=ConciseMethod): + + classic_contract._return_data_normalizers += CONCISE_NORMALIZERS + self._classic_contract = classic_contract + self.address = self._classic_contract.address + + protected_fn_names = [fn for fn in dir(self) if not fn.endswith('__')] + + for fn_name in self._classic_contract.functions: + + # Override namespace collisions + if fn_name in protected_fn_names: + _concise_method = mk_collision_prop(fn_name) + + else: + _classic_method = getattr( + self._classic_contract.functions, + fn_name) + + _concise_method = method_class( + _classic_method, + self._classic_contract._return_data_normalizers + ) + + setattr(self, fn_name, _concise_method) + + @classmethod + def factory(cls, *args, **kwargs): + return compose(cls, Contract.factory(*args, **kwargs)) + + +def _none_addr(datatype, data): + if datatype == 'address' and int(data, base=16) == 0: + return (datatype, None) + else: + return (datatype, data) + + +CONCISE_NORMALIZERS = ( + _none_addr, +) + + +class ImplicitMethod(ConciseMethod): + def __call_by_default(self, args): + function_abi = find_matching_fn_abi(self._function.contract_abi, + fn_identifier=self._function.function_identifier, + args=args) + + return function_abi['constant'] if 'constant' in function_abi.keys() else False + + def __call__(self, *args, **kwargs): + # Modifier is not provided and method is not constant/pure do a transaction instead + if not kwargs and not self.__call_by_default(args): + return super().__call__(*args, transact={}) + else: + return super().__call__(*args, **kwargs) + + +class ImplicitContract(ConciseContract): + ''' + ImplicitContract class is similar to the ConciseContract class + however it performs a transaction instead of a call if no modifier + is given and the method is not marked 'constant' in the ABI. + + The transaction will use the default account to send the transaction. + + This call + + > contract.withdraw(amount) + + is equivalent to this call in the classic contract: + + > contract.functions.withdraw(amount).transact({}) + ''' + def __init__(self, classic_contract, method_class=ImplicitMethod): + super().__init__(classic_contract, method_class=method_class) + + +class NonExistentFallbackFunction: + @staticmethod + def _raise_exception(): + raise FallbackNotFound("No fallback function was found in the contract ABI.") + + def __getattr__(self, attr): + return NonExistentFallbackFunction._raise_exception + + +class ContractFunction: + """Base class for contract functions + + A function accessed via the api contract.functions.myMethod(*args, **kwargs) + is a subclass of this class. + """ + address = None + function_identifier = None + web3 = None + contract_abi = None + abi = None + transaction = None + arguments = None + vmtype=None + + def __init__(self, abi=None): + self.abi = abi + self.fn_name = type(self).__name__ + + def __call__(self, *args, **kwargs): + clone = copy.copy(self) + if args is None: + clone.args = tuple() + else: + clone.args = args + + if kwargs is None: + clone.kwargs = {} + else: + clone.kwargs = kwargs + clone._set_function_info() + return clone + + def _set_function_info(self): + if not self.abi: + self.abi = find_matching_fn_abi( + self.contract_abi, + self.function_identifier, + self.args, + self.kwargs + ) + if self.function_identifier is FallbackFn: + self.selector = encode_hex(b'') + elif is_text(self.function_identifier): + self.selector = encode_hex(function_abi_to_4byte_selector(self.abi)) + else: + raise TypeError("Unsupported function identifier") + + self.arguments = merge_args_and_kwargs(self.abi, self.args, self.kwargs) + + def call(self, transaction=None, block_identifier='latest'): + """ + Execute a contract function call using the `platon_call` interface. + + This method prepares a ``Caller`` object that exposes the contract + functions and public variables as callable Python functions. + + Reading a public ``owner`` address variable example: + + .. code-block:: python + + ContractFactory = w3.eth.contract( + abi=wallet_contract_definition["abi"] + ) + + # Not a real contract address + contract = ContractFactory("0x2f70d3d26829e412A602E83FE8EeBF80255AEeA5") + + # Read "owner" public variable + addr = contract.functions.owner().call() + + :param transaction: Dictionary of transaction info for web3 interface + :return: ``Caller`` object that has contract public functions + and variables exposed as Python methods + """ + if transaction is None: + call_transaction = {} + else: + call_transaction = dict(**transaction) + + if 'data' in call_transaction: + raise ValueError("Cannot set data in call transaction") + + if self.address: + call_transaction.setdefault('to', self.address) + if self.web3.eth.defaultAccount is not empty: + call_transaction.setdefault('from', self.web3.eth.defaultAccount) + + if 'to' not in call_transaction: + if isinstance(self, type): + raise ValueError( + "When using `Contract.[methodtype].[method].call()` from" + " a contract factory you " + "must provide a `to` address with the transaction" + ) + else: + raise ValueError( + "Please ensure that this contract instance has an address." + ) + + block_id = parse_block_identifier(self.web3, block_identifier) + + return call_contract_function( + self.web3, + self.address, + self._return_data_normalizers, + self.function_identifier, + call_transaction, + self.vmtype, + block_id, + self.contract_abi, + self.abi, + *self.args, + **self.kwargs + ) + + def transact(self, transaction=None): + if transaction is None: + transact_transaction = {} + else: + transact_transaction = dict(**transaction) + + if 'data' in transact_transaction: + raise ValueError("Cannot set data in transact transaction") + + if self.address is not None: + transact_transaction.setdefault('to', self.address) + if self.web3.eth.defaultAccount is not empty: + transact_transaction.setdefault('from', self.web3.eth.defaultAccount) + + if 'to' not in transact_transaction: + if isinstance(self, type): + raise ValueError( + "When using `Contract.transact` from a contract factory you " + "must provide a `to` address with the transaction" + ) + else: + raise ValueError( + "Please ensure that this contract instance has an address." + ) + + return transact_with_contract_function( + self.address, + self.web3, + self.function_identifier, + transact_transaction, + self.contract_abi, + self.abi, + *self.args, + **self.kwargs + ) + + def estimateGas(self, transaction=None): + if transaction is None: + estimate_gas_transaction = {} + else: + estimate_gas_transaction = dict(**transaction) + + if 'data' in estimate_gas_transaction: + raise ValueError("Cannot set data in estimateGas transaction") + if 'to' in estimate_gas_transaction: + raise ValueError("Cannot set to in estimateGas transaction") + + if self.address: + estimate_gas_transaction.setdefault('to', self.address) + if self.web3.eth.defaultAccount is not empty: + estimate_gas_transaction.setdefault('from', self.web3.eth.defaultAccount) + + if 'to' not in estimate_gas_transaction: + if isinstance(self, type): + raise ValueError( + "When using `Contract.estimateGas` from a contract factory " + "you must provide a `to` address with the transaction" + ) + else: + raise ValueError( + "Please ensure that this contract instance has an address." + ) + + return estimate_gas_for_function( + self.address, + self.web3, + self.function_identifier, + estimate_gas_transaction, + self.contract_abi, + self.abi, + *self.args, + **self.kwargs + ) + + def buildTransaction(self, transaction=None): + """ + Build the transaction dictionary without sending + """ + if transaction is None: + built_transaction = {} + else: + built_transaction = dict(**transaction) + + if 'data' in built_transaction: + raise ValueError("Cannot set data in build transaction") + + if not self.address and 'to' not in built_transaction: + raise ValueError( + "When using `ContractFunction.buildTransaction` from a contract factory " + "you must provide a `to` address with the transaction" + ) + if self.address and 'to' in built_transaction: + raise ValueError("Cannot set to in contract call build transaction") + + if self.address: + built_transaction.setdefault('to', self.address) + + if 'to' not in built_transaction: + raise ValueError( + "Please ensure that this contract instance has an address." + ) + + return build_transaction_for_function( + self.address, + self.web3, + self.function_identifier, + built_transaction, + self.contract_abi, + self.abi, + *self.args, + **self.kwargs + ) + + @combomethod + def _encode_transaction_data(cls): + return add_0x_prefix(encode_abi(cls.web3, cls.abi, cls.arguments, cls.vmtype, cls.selector, cls.abi)) + + _return_data_normalizers = tuple() + + @classmethod + def factory(cls, class_name, **kwargs): + return PropertyCheckingFactory(class_name, (cls,), kwargs)(kwargs.get('abi')) + + def __repr__(self): + if self.abi: + _repr = '' + return '' % self.fn_name + + +class ContractEvent: + """Base class for contract events + + An event accessed via the api contract.events.myEvents(*args, **kwargs) + is a subclass of this class. + """ + address = None + event_name = None + web3 = None + contract_abi = None + abi = None + vmtype=None + + def __init__(self, *argument_names): + + if argument_names is None: + self.argument_names = tuple() + else: + self.argument_names = argument_names + + self.abi = self._get_event_abi() + + @classmethod + def _get_event_abi(cls): + return find_matching_event_abi( + cls.contract_abi, + event_name=cls.event_name) + + @combomethod + def processReceipt(self, txn_receipt): + return self._parse_logs(txn_receipt) + + @to_tuple + def _parse_logs(self, txn_receipt): + for log in txn_receipt['logs']: + try: + decoded_log = get_event_data(self.abi, log) + except MismatchedABI: + continue + yield decoded_log + + @combomethod + def createFilter( + self, *, # PEP 3102 + argument_filters=None, + fromBlock=None, + toBlock="latest", + address=None, + topics=None): + """ + Create filter object that tracks logs emitted by this contract event. + :param filter_params: other parameters to limit the events + """ + if fromBlock is None: + raise TypeError("Missing mandatory keyword argument to createFilter: fromBlock") + + if argument_filters is None: + argument_filters = dict() + + _filters = dict(**argument_filters) + + data_filter_set, event_filter_params = construct_event_filter_params( + self._get_event_abi(), + contract_address=self.address, + argument_filters=_filters, + fromBlock=fromBlock, + toBlock=toBlock, + address=address, + topics=topics, + ) + + log_data_extract_fn = functools.partial(get_event_data, self._get_event_abi()) + + log_filter = self.web3.eth.filter(event_filter_params) + + log_filter.set_data_filters(data_filter_set) + log_filter.log_entry_formatter = log_data_extract_fn + log_filter.filter_params = event_filter_params + + return log_filter + + @classmethod + def factory(cls, class_name, **kwargs): + return PropertyCheckingFactory(class_name, (cls,), kwargs) + + +def call_contract_function( + web3, + address, + normalizers, + function_identifier, + transaction, + vmtype=None, + block_id=None, + contract_abi=None, + fn_abi=None, + *args, + **kwargs): + """ + Helper function for interacting with a contract function using the + `platon_call` API. + """ + call_transaction = prepare_transaction( + address, + web3, + fn_identifier=function_identifier, + contract_abi=contract_abi, + fn_abi=fn_abi, + vmtype=vmtype, + transaction=transaction, + fn_args=args, + fn_kwargs=kwargs, + ) + + if block_id is None: + return_data = web3.eth.call(call_transaction) + else: + return_data = web3.eth.call(call_transaction, block_identifier=block_id) + + if fn_abi is None: + fn_abi = find_matching_fn_abi(contract_abi, function_identifier, args, kwargs) + + output_types = get_abi_output_types(fn_abi) + + try: + output_data = decode_abi(output_types, return_data) + + except DecodingError as e: + # Provide a more helpful error message than the one provided by + # eth-abi-utils + is_missing_code_error = ( + return_data in ACCEPTABLE_EMPTY_STRINGS and + web3.eth.getCode(address) in ACCEPTABLE_EMPTY_STRINGS + ) + if is_missing_code_error: + msg = ( + "Could not transact with/call contract function, is contract " + "deployed correctly and chain synced?" + ) + else: + msg = ( + "Could not decode contract function call {} return data {} for " + "output_types {}".format( + function_identifier, + return_data, + output_types + ) + ) + raise BadFunctionCallOutput(msg) from e + + _normalizers = itertools.chain( + BASE_RETURN_NORMALIZERS, + normalizers, + ) + normalized_data = map_abi_data(_normalizers, output_types, output_data) + laxdata = [] + if output_types == ['address']: + laxdata = tobech32address(address[:3], normalized_data[0]) + return laxdata[0] + elif output_types == ['address[]']: + for i in range(len(normalized_data[0])): + laxdata.append(tobech32address(address[:3], normalized_data[0][i])) + return laxdata + else: + if len(normalized_data) == 1: + return normalized_data[0] + else: + return normalized_data + + +def parse_block_identifier(web3, block_identifier): + if isinstance(block_identifier, int): + return parse_block_identifier_int(web3, block_identifier) + elif block_identifier in ['latest', 'earliest', 'pending']: + return block_identifier + elif isinstance(block_identifier, bytes) or is_hex_encoded_block_hash(block_identifier): + return web3.eth.getBlock(block_identifier)['number'] + else: + raise BlockNumberOutofRange + + +def parse_block_identifier_int(web3, block_identifier_int): + if block_identifier_int >= 0: + block_num = block_identifier_int + else: + last_block = web3.eth.getBlock('latest')['number'] + block_num = last_block + block_identifier_int + 1 + if block_num < 0: + raise BlockNumberOutofRange + return block_num + + +def transact_with_contract_function( + address, + web3, + function_name=None, + transaction=None, + contract_abi=None, + fn_abi=None, + *args, + **kwargs): + """ + Helper function for interacting with a contract function by sending a + transaction. + """ + transact_transaction = prepare_transaction( + address, + web3, + fn_identifier=function_name, + contract_abi=contract_abi, + transaction=transaction, + fn_abi=fn_abi, + fn_args=args, + fn_kwargs=kwargs, + ) + + txn_hash = web3.eth.sendTransaction(transact_transaction) + return txn_hash + + +def estimate_gas_for_function( + address, + web3, + fn_identifier=None, + transaction=None, + contract_abi=None, + fn_abi=None, + *args, + **kwargs): + """Estimates gas cost a function call would take. + + Don't call this directly, instead use :meth:`Contract.estimateGas` + on your contract instance. + """ + estimate_transaction = prepare_transaction( + address, + web3, + fn_identifier=fn_identifier, + contract_abi=contract_abi, + fn_abi=fn_abi, + transaction=transaction, + fn_args=args, + fn_kwargs=kwargs, + ) + + gas_estimate = web3.eth.estimateGas(estimate_transaction) + return gas_estimate + + +def build_transaction_for_function( + address, + web3, + function_name=None, + transaction=None, + contract_abi=None, + fn_abi=None, + *args, + **kwargs): + """Builds a dictionary with the fields required to make the given transaction + + Don't call this directly, instead use :meth:`Contract.buildTransaction` + on your contract instance. + """ + prepared_transaction = prepare_transaction( + address, + web3, + fn_identifier=function_name, + contract_abi=contract_abi, + fn_abi=fn_abi, + transaction=transaction, + fn_args=args, + fn_kwargs=kwargs, + ) + + prepared_transaction = fill_transaction_defaults(web3, prepared_transaction) + + return prepared_transaction + + +def find_functions_by_identifier(contract_abi, web3, address, callable_check): + fns_abi = filter_by_type('function', contract_abi) + return [ + ContractFunction.factory( + fn_abi['name'], + web3=web3, + contract_abi=contract_abi, + address=address, + function_identifier=fn_abi['name'], + abi=fn_abi + ) + for fn_abi in fns_abi + if callable_check(fn_abi) + ] + + +def get_function_by_identifier(fns, identifier): + if len(fns) > 1: + raise ValueError( + 'Found multiple functions with matching {0}. ' + 'Found: {1!r}'.format(identifier, fns) + ) + elif len(fns) == 0: + raise ValueError( + 'Could not find any function with matching {0}'.format(identifier) + ) + return fns[0] diff --git a/debug/debug.py b/debug/debug.py new file mode 100644 index 0000000..e750775 --- /dev/null +++ b/debug/debug.py @@ -0,0 +1,259 @@ +import random +import time +from client_sdk_python import HTTPProvider, Web3 +from client_sdk_python import eth, ppos, pip +from client_sdk_python.middleware import geth_poa_middleware +from hexbytes import HexBytes +from client_sdk_python.packages.platon_account.account import Account +from client_sdk_python.packages.platon_keys.utils.address import MIANNETHRP, TESTNETHRP + + +# 通用信息 +node_url = 'http://192.168.120.121:6789' +chain_id = 201018 +HRP = MIANNETHRP +w3 = Web3(HTTPProvider(node_url), chain_id=chain_id) +w3.middleware_stack.inject(geth_poa_middleware, layer=0) +platon = eth.PlatON(w3) +ppos = ppos.Ppos(w3) +pip = pip.Pip(w3) +pip_trans_cfg = {'gasPrice': 3000000000000000} + +# 创建账户 +def create_account(): + print("==== create account =====") + account = w3.platon.account.create(net_type=HRP) + address = account.address + prikey = account.privateKey.hex()[2:] + # check = platon.account.privateKeyToAccount(prikey, net_type=w3.net_type) + # assert address == check + print(f"create account = {address}, {prikey}") + return address, prikey + +# 转账交易 +def transfer(from_privatekey, to_address, amount): + print("==== transfer =====") + from_address = Account.privateKeyToAccount(from_privatekey, HRP).address + nonce = w3.platon.getTransactionCount(from_address) + transaction_dict = { + "to": to_address, + "gasPrice": w3.eth.gasPrice, + "gas": 21000, + "nonce": nonce, + "data": '', + "chainId": chain_id, + "value": amount, + } + signedTransactionDict = w3.platon.account.signTransaction( + transaction_dict, from_privatekey + ) + data = signedTransactionDict.rawTransaction + result = HexBytes(w3.platon.sendRawTransaction(data)).hex() + result = w3.platon.waitForTransactionReceipt(result) + print(f"transfer staking result = {result}") + +# 锁仓交易 +def create_restricting_plan(from_private_key, to_address, restricting_plan): + print("==== create restricting plan =====") + # ppos.need_analyze = False + result = ppos.createRestrictingPlan(to_address, restricting_plan, from_private_key) + print(f"create restricting plan result = {result}") + +# 创建质押 +def create_staking(staking_private_key, staking_type, node_url, node_id, bls_pubkey, amount=10 ** 18 * 2000000, reward_per=1000): + print("==== create staking =====") + w3 = Web3(HTTPProvider(node_url), chain_id=chain_id) + program_version = w3.admin.getProgramVersion()['Version'] + version_sign = w3.admin.getProgramVersion()['Sign'] + bls_proof = w3.admin.getSchnorrNIZKProve() + benifit_address = Account.privateKeyToAccount(staking_private_key, HRP).address + result = w3.ppos.createStaking(staking_type, benifit_address, node_id, 'external_id', 'node_name', 'website', 'details', + amount, program_version, version_sign, bls_pubkey, bls_proof, staking_private_key, reward_per) + print(f"create staking result = {result}") + +# 增持质押 +def increase_staking(staking_private_key, node_id, amount=10 ** 18 * 100): + print("==== increase staking =====") + result = w3.ppos.increaseStaking(0, node_id, amount, staking_private_key) + print(f'incress staking result = {result}') + +# 修改质押信息 +def edit_staking(staking_private_key, node_id, benifit_address=None, external_id=None, node_name=None, website=None, details=None, reward_per=None): + print("==== edit staking =====") + result = w3.ppos.editCandidate(staking_private_key, node_id, benifit_address, external_id, node_name, website, details, reward_per) + print(f'edit staking result = {result}') + +# 解除质押 +def withdrew_staking(staking_private_key, node_id): + print("==== withdrew staking =====") + result = w3.ppos.withdrewStaking(node_id, staking_private_key) + print(f'withdrew staking result = {result}') + +# 查询质押信息 +def get_staking_info(node_id): + print("==== get staking info =====") + result = w3.ppos.getValidatorList() + print(f'get validator list = {result}') + result = w3.ppos.getVerifierList() + print(f'get verifier list = {result}') + result = w3.ppos.getCandidateList() + print(f'get candidate list = {result}') + result = w3.ppos.getCandidateInfo(node_id) + print(f'get candidate info = {result}') + +# 创建委托 +def delegation(delegation_private_key, node_id, amount=10 * 10 ** 18): + print("==== delegation =====") + resutl = w3.ppos.delegate(0, node_id, amount, delegation_private_key) + print(f'delegation result = {resutl}') + +# 解除委托 +def undelegation(delegation_private_key, node_id, amount=1 * 10 ** 18): + print("==== undelegation =====") + delegation_address = Account.privateKeyToAccount(delegation_private_key, HRP).address + result = w3.ppos.getRelatedListByDelAddr(delegation_address) + print(f'get related list = {result}') + block_number = result.get('Ret')[0].get('StakingBlockNum') + assert block_number != '' + result = w3.ppos.withdrewDelegate(block_number, node_id, amount, delegation_private_key) + print(f'undelegation result = {result}') + +# 查询委托信息 +def get_delegation_list(delegation_address): + print("==== get delegation list =====") + result = w3.ppos.getRelatedListByDelAddr(delegation_address) + print(f'get delegation list = {result}') + +# 领取委托分红 +def withdraw_delegate_reward(delegate_private_key): + print("==== withdraw delegate reward =====") + result = w3.ppos.withdrawDelegateReward(delegate_private_key) + print(f'withdraw delegate result = {result}') + +# 创建升级提案 +def create_version_proposal(node_private_key, node_id, upgrade_version, voting_rounds): + print("==== create version proposal =====") + result = w3.pip.submitVersion(node_id, str(time.time()), upgrade_version, voting_rounds, node_private_key, pip_trans_cfg) + print(f'create version proposal result = {result}') + +# 查询提案id +def get_proposal_list(): + print("==== get proposal list =====") + pip_list = w3.pip.listProposal() + print(f"proposal list = {pip_list}") + +# 提案投票 +def version_proposal_vote(node_private_key, node_url, node_id, vote_type): + print("==== version proposal vote =====") + w3 = Web3(HTTPProvider(node_url), chain_id=chain_id) + program_version = w3.admin.getProgramVersion()['Version'] + version_sign = w3.admin.getProgramVersion()['Sign'] + proposal_id = w3.pip.listProposal().get('Ret')[0].get('ProposalID') + assert proposal_id != '' + result = w3.pip.vote(node_id, proposal_id, vote_type, program_version, version_sign, node_private_key) + print(f'version proposal vote result = {result}, {proposal_id}') + +# 获取版本号 +def get_version(): + print("==== get version =====") + result = w3.pip.getActiveVersion() + print(f'version = {result}') + + +def wait_block(block_number): + print("==== wait block ====") + current_block = platon.blockNumber + end_block = current_block + block_number + while current_block < end_block: + print(f'wait block: {current_block} -> {end_block}') + time.sleep(5) + current_block = platon.blockNumber + + +if __name__ == '__main__': + main_address, main_private_key = 'atx1zkrxx6rf358jcvr7nruhyvr9hxpwv9unj58er9', 'f51ca759562e1daf9e5302d121f933a8152915d34fcbc27e542baf256b5e4b74' + + # # **** 交易模块 **** + # from_address, from_private_key = create_account() + # to_address, to_private_key = create_account() + # transfer(main_private_key, from_address, 100 * 10 ** 18) + # 普通交易 + # transfer(main_private_key, 'atx1t5kdy77uycd06aezuv2lddnsus9w02tmxpdgz2', 10000 * 10 ** 18) + # 锁仓交易 + # plan = [{'Epoch': 0, 'Amount': 80 * 10 ** 18}] + # create_restricting_plan(main_private_key, 'atx1c85wwztzpjefcvaev6wxpsrqp2gpfjyp6lmfqd', plan) + + # # **** 经济模型模块 **** + # node_url = 'http://192.168.120.124:6790' + # node_id = '7038eb30c06683c97282d0d7acbf939c15bcfc390eb461983445c2d58328d88b85a3d4c79867c18a5ed9442a13062c4b5a9f9e03ea7026e000c9b13c2a1d3255' + # bls_pubkey = 'd2f1be8a9832048f745d30095e483fd187dd37972ef7bd6491bc6cd957372ab16ca3f9d6f4c20a41b9b9d235fca51f12ab2c21029b495647692482714573bef10d444858ddc404c97d117cb7950b1b157e3bffb1be13f31623612fd057efc605' + # staking_address, staking_private_key = 'atp1elg3q9hw5cy3hztg0vqwglhk6tjmwk6e0na9wj', '1fa6c50d48c44f8bc289536c4a607a628524adea80536767b54041499579a887' + # staking_address, staking_private_key = create_account() + # delegation_address, delegation_private_key = 'atx16g303js6tushq236fhv5cmr8tw272cg9279tcl', 'b854c86a25498ce21035d3fabc7dbe784b4288ad3bd9580437bd0250014 + # e40c1' + # # 创建质押 + # plan = [{'Epoch': 2, 'Amount': 2000 * 10 ** 18}, + # {'Epoch': 4, 'Amount': 2000 * 10 ** 18}, + # {'Epoch': 8, 'Amount': 2000 * 10 ** 18}, + # {'Epoch': 16, 'Amount': 2000 * 10 ** 18}, + # {'Epoch': 32, 'Amount': 2000 * 10 ** 18}, + # {'Epoch': 64, 'Amount': 5000 * 10 ** 18}, + # {'Epoch': 128, 'Amount': 5000 * 10 ** 18}, + # {'Epoch': 256, 'Amount': 5000 * 10 ** 18}] + # create_restricting_plan(main_private_key, staking_address, plan) + # transfer(main_private_key, staking_address, 20010 * 10 ** 18) + # create_staking(staking_private_key, 0, node_url, node_id, bls_pubkey, 20000 * 10 ** 18, 1000) + # # 增持质押 + # transfer(main_private_key, staking_address, 10 * 10 ** 18) + # increase_staking(staking_private_key, node_id, 10 * 10 ** 18) + # # 修改质押信息 + # benifit_address = Account.privateKeyToAccount(staking_private_key, HRP).address + # edit_staking(staking_private_key, node_id, external_id='shinnng') + # # 创建委托 + # transfer(main_private_key, delegation_address, 11 * 10 ** 18) + # delegation(delegation_private_key, node_id, 10 * 10 ** 18) + # # 撤销委托 + # amout = random.randint(1, 10) + # undelegation(delegation_private_key, node_id, amout) + # # 领取委托分红 + # withdraw_delegate_reward(delegation_private_key) + # # 解除质押 + # wait_block(40 * 4 * 2) + # withdrew_staking(staking_private_key, node_id) + + # # **** 治理模块 **** + # upgrade_version = 3584 + # upgrade_voting_rounds = 30 + # # # 升级提案 + # staking_private_key = '85128e542f92384a4f8259f44bea0a70425a7f79e722ab4c0cbbd811154ec553' + # node_id = 'bc9dabae54a13202ec765c1537c57b9f6659161596eae7c0344a606e9396c63c96a2a76aadc320100e9a56c5acdb8faddfb61733bddeff7b9f261ac54a46d775' + # create_version_proposal(staking_private_key, node_id, upgrade_version, upgrade_voting_rounds) + # # 提案投票 + cdf_node_list = [('http://192.168.120.121:6789', '35bb5daad814fe902030cba6fd2d3ec60906dab70ba5df4d42a19448d300ab203cfd892c325f6716965dd93d8de2a377a2806c9703b69b68287577c70f9e7c07', ''), + ('http://192.168.120.122:6789', '5030440865a11ce0ab1441d3977647b0606e1f34897cfea1e55ea13d91c7a7fc5575fd3d1614f005384dc7e6974e4f96193d38883507eebcdcc29ca57d19499d'), + ('http://192.168.120.123:6789', '4555b0d40b857f50186703c48bc342f2e15473823627d5aa817dabe992171361ccf9d8c57967077dc5500eec65b5b9beb3f56efae4ffd3ddbf2753f4499e8c2e'), + ('http://192.168.120.124:6789', 'e51278714f6d8218900a311b251753f4f9408295561c4a913385e7817bbe6e69056c9f3a46dd56284d311f1e080f82d1edff98502af525fd19d233dd2406ec54')] + # node_url = 'http://192.168.120.123:6790' + # node_id = 'bc9dabae54a13202ec765c1537c57b9f6659161596eae7c0344a606e9396c63c96a2a76aadc320100e9a56c5acdb8faddfb61733bddeff7b9f261ac54a46d775' + private_key = '85128e542f92384a4f8259f44bea0a70425a7f79e722ab4c0cbbd811154ec553' + + for node_url, node_id in cdf_node_list: + print(node_url, node_id) + version_proposal_vote(private_key, node_url, node_id, 1) + # # 查询提案 + # get_proposal_list() + + # # **** 调试信息 **** + # print(platon.blockNumber) + # print(platon.getBalance(main_address)) + # print(platon.gasPrice) + # print(ppos.getRestrictingInfo('atx1c85wwztzpjefcvaev6wxpsrqp2gpfjyp6lmfqd')) + # print(platon.getTransactionCount('atx1zkrxx6rf358jcvr7nruhyvr9hxpwv9unj58er9')) + # print(platon.waitForTransactionReceipt('0xda81aab7e6d9f5188081fbd281fd0eaaebef1f1be03ff2c98fd1f76c36c16ec5')) + # print(platon.getCode('atx1rdlcxzxk88e7k7mm0w93ald07g52l6pw97gzzz')) + # print(ppos.getValidatorList()) + # print(ppos.getVerifierList()) + # print(pip.listProposal()) + # print(ppos.getCandidateList()) + # print(pip.getAccuVerifiersCount('0x8568213e8014bcdaa38132e1df05ec2f35471ebdafd737f452a8393cc105611c', '0x8c80f64bfe241494d9b3c6509bfe2ae30eb51cf9a56277d407394bbcf00071c8')) + # print(pip.getActiveVersion()) diff --git a/ens/auto.py b/ens/auto.py deleted file mode 100644 index 690f637..0000000 --- a/ens/auto.py +++ /dev/null @@ -1,3 +0,0 @@ -from ens import ENS - -ns = ENS() diff --git a/requirements-docs.txt b/requirements-docs.txt deleted file mode 100644 index e9704b8..0000000 --- a/requirements-docs.txt +++ /dev/null @@ -1 +0,0 @@ -.[docs] diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..890b85e --- /dev/null +++ b/requirements.txt @@ -0,0 +1,20 @@ +pywin32==227 +idna==2.7 +hexbytes==0.1.0 +eth_rlp==0.1.2 +numpy==1.19.1 +requests==2.20.0 +pysha3==1.0.2 +websockets==6.0 +eth_hash==0.2.0 +rlp==1.1.0 +tqdm==4.49.0 +lru_dict==1.1.6 +cytoolz==0.10.1 +parsimonious==0.8.1 +data==0.4 +ethpm==0.1.3 +flaky==3.7.0 +lru==0.1 +pycryptodome==3.9.9 +sha3==0.2.1 diff --git a/setup.py b/setup.py index 9dbf9da..c9bddee 100644 --- a/setup.py +++ b/setup.py @@ -58,32 +58,35 @@ ) setup( - name='client_sdk_python', + name='client-sdk-python', # *IMPORTANT*: Don't manually change the version here. Use the 'bumpversion' utility. - version='0.7.0', - description="""PlatON Client SDK python""", + version='1.0.0', + description="""PlatON python SDK""", # long_description_markdown_filename='README.md', - author='Piper awake', - author_email='hietel366435@gmail.com', + author='Piper shinnng', + author_email='shinnng@outlook.com', url='https://github.com/PlatONnetwork/client-sdk-python', include_package_data=True, install_requires=[ "toolz>=0.9.0,<1.0.0;implementation_name=='pypy'", "cytoolz>=0.9.0,<1.0.0;implementation_name=='cpython'", - "eth-abi>=1.2.0,<2.0.0", - "platon-account>=0.1.2", + "six>=1.15.0", + "numpy>=1.19.0", + # "platon-account>=0.1.2", "eth-utils>=1.2.0,<2.0.0", "hexbytes>=0.1.0,<1.0.0", "lru-dict>=1.1.6,<2.0.0", "eth-hash[pycryptodome]>=0.2.0,<1.0.0", - "requests>=2.16.0,<3.0.0", + "requests>=2.11.0,<3.0.0", "websockets>=6.0.0,<7.0.0", - "pypiwin32>=223;platform_system=='Windows'", 'rlp', 'pysha3' + "pypiwin32>=223;platform_system=='Windows'", 'rlp', 'pysha3', 'eth_rlp', + "attrdict>=2.0.1", + "parsimonious>=0.8.1" ], setup_requires=['setuptools-markdown'], python_requires='>=3.6,<4', extras_require=extras_require, - py_modules=['web3', 'ens'], + py_modules=['web3'], license="MIT", zip_safe=False, keywords='platon', diff --git a/tests/AddressArrayTest.py b/tests/AddressArrayTest.py new file mode 100644 index 0000000..48ce8da --- /dev/null +++ b/tests/AddressArrayTest.py @@ -0,0 +1,84 @@ +from client_sdk_python import Web3,HTTPProvider +from client_sdk_python.eth import PlatON + + +true = True +false = False + +w3 = Web3(HTTPProvider("http://10.10.8.209:6789")) +platon = PlatON(w3) +print(w3.isConnected()) +from_address = "atp1uqug0zq7rcxddndleq4ux2ft3tv6dqljhyq6jl" +send_privatekey = "983759fe9aac227c535b21d78792d79c2f399b1d43db46ae6d50a33875301557" + + +bytecode ='608060405234801561001057600080fd5b506102b7806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c806371e5ee5f1461003b578063e590cf7f146100a9575b600080fd5b6100676004803603602081101561005157600080fd5b81019080803590602001909291905050506101b6565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61015f600480360360208110156100bf57600080fd5b81019080803590602001906401000000008111156100dc57600080fd5b8201836020820111156100ee57600080fd5b8035906020019184602083028401116401000000008311171561011057600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f8201169050808301925050505050505091929192905050506101f2565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b838110156101a2578082015181840152602081019050610187565b505050509050019250505060405180910390f35b600081815481106101c357fe5b906000526020600020016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60607324a42648378add5ba81c76b70caa84a9546279228260008151811061021657fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505081905091905056fea265627a7a7231582095e2e313d166a0c2ce2537b858b388dfa0f631c0c8622519a5b282644d0682ef64736f6c63782c302e352e31332d646576656c6f702e323032302e352e31382b636f6d6d69742e33616239633638642e6d6f64005c' + +abi = [{'constant': True, 'inputs': [{'internalType': 'address[]', 'name': 'arr', 'type': 'address[]'}], 'name': 'IuputArray', 'outputs': [{'internalType': 'address[]', 'name': '', 'type': 'address[]'}], 'payable': False, 'stateMutability': 'view', 'type': 'function'}, {'constant': True, 'inputs': [{'internalType': 'uint256', 'name': '', 'type': 'uint256'}], 'name': 'arr', 'outputs': [{'internalType': 'address', 'name': '', 'type': 'address'}], 'payable': False, 'stateMutability': 'view', 'type': 'function'}] +# Instantiate and deploy contract +Payable = platon.contract(abi=abi, bytecode=bytecode) + +# # Submit the transaction that deploys the contract +# tx_hash = Greeter.constructor().transact() +# +# # Wait for the transaction to be mined, and get the transaction receipt +# tx_receipt = platon.waitForTransactionReceipt(tx_hash) +# print(tx_receipt) +# +# contract_instance = platon.contract(address=contractAddress, abi=abi) +def SendTxn(txn): + signed_txn = platon.account.signTransaction(txn,private_key=send_privatekey) + res = platon.sendRawTransaction(signed_txn.rawTransaction).hex() + txn_receipt = platon.waitForTransactionReceipt(res) + print(res) + return txn_receipt + +txn = Payable.constructor().buildTransaction( + { + 'chainId':201018, + 'nonce':platon.getTransactionCount(from_address), + 'gas':1500000, + 'value':0, + 'gasPrice':1000000000, + } +) + +tx_receipt = SendTxn(txn) +print(tx_receipt) + +# Create the contract instance with the newly-deployed address +payable = platon.contract(address=tx_receipt.contractAddress, abi=abi) + +# hrpgot, data = bech32.decode("lax", from_address) +# address = to_checksum_address(bytes(data)) +# print(address) +address = ["atp1uqug0zq7rcxddndleq4ux2ft3tv6dqljhyq6jl","atp1uqug0zq7rcxddndleq4ux2ft3tv6dqljhyq6jl"] + +# Display the default greeting from the contract +print('Get Address : {}'.format( + payable.functions.IuputArray(address).call() +)) +# Get Address : ['atp1yjjzvjph3tw4h2quw6mse25y492xy7fzc70hra', 'atp1uqug0zq7rcxddndleq4ux2ft3tv6dqljhyq6jl'] + +# print('Setting the greeting to Nihao...') +# address1='lax15r7gxd0c9xqxu0vca35wz0zch5qfyayj9ed3r2' +# tx_hash = payable.functions.transfer(address1).transact( +# { +# 'from':from_address, +# 'gas':1500000, +# 'value':10000, +# } +# ) +# print(tx_hash) +# +# # Wait for transaction to be mined... +# platon.waitForTransactionReceipt(tx_hash) +# +# # Display the new greeting value +# print('Updated contract greeting: {}'.format( +# payable.functions.greet().call() +# )) + +# # When issuing a lot of reads, try this more concise reader: +# reader = ConciseContract(greeter) +# assert reader.greet() == "Nihao" \ No newline at end of file diff --git a/tests/AddressTest(1).py b/tests/AddressTest(1).py new file mode 100644 index 0000000..e0d222b --- /dev/null +++ b/tests/AddressTest(1).py @@ -0,0 +1,108 @@ +from client_sdk_python import Web3,HTTPProvider +from client_sdk_python.eth import PlatON + + +# Solidity source code +# contract_source_code = ''' +# pragma solidity ^0.5.0; +# +# contract Payable { +# //获取地址的余额 +# function getBalances(address addr) view public returns (uint){ +# return addr.balance; +# } +# +# function transfer(address payable addr) public payable{ +# addr.transfer(msg.value); +# } +# } +# ''' + +true = True +false = False + + +w3 = Web3(HTTPProvider("http://10.10.8.209:6789")) +platon = PlatON(w3) +print(w3.isConnected()) +# w3 = Web3(HTTPProvider("http://10.1.1.5:6789")) +# platon = PlatON(w3) +# print(w3.isConnected()) +# from_address = "lax1uqug0zq7rcxddndleq4ux2ft3tv6dqljphydrl" +from_address = "lax1du4w3q0h5gpxh2vpdvtl7m8h2p9qj40a2krhx7" +print(from_address) +# send_privatekey = "983759fe9aac227c535b21d78792d79c2f399b1d43db46ae6d50a33875301557" +send_privatekey = "983759fe9aac227c535b21d78792d79c2f399b1d43db46ae6d50a33875301557" + +# bytecode = '608060405234801561001057600080fd5b506040518060400160405280600581526020017f48656c6c6f0000000000000000000000000000000000000000000000000000008152506000908051906020019061005c929190610062565b50610107565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100a357805160ff19168380011785556100d1565b828001600101855582156100d1579182015b828111156100d05782518255916020019190600101906100b5565b5b5090506100de91906100e2565b5090565b61010491905b808211156101005760008160009055506001016100e8565b5090565b90565b610465806101166000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c8063a413686214610046578063cfae321714610101578063ef690cc014610184575b600080fd5b6100ff6004803603602081101561005c57600080fd5b810190808035906020019064010000000081111561007957600080fd5b82018360208201111561008b57600080fd5b803590602001918460018302840111640100000000831117156100ad57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050610207565b005b610109610221565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561014957808201518184015260208101905061012e565b50505050905090810190601f1680156101765780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61018c6102c3565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101cc5780820151818401526020810190506101b1565b50505050905090810190601f1680156101f95780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b806000908051906020019061021d929190610361565b5050565b606060008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156102b95780601f1061028e576101008083540402835291602001916102b9565b820191906000526020600020905b81548152906001019060200180831161029c57829003601f168201915b5050505050905090565b60008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156103595780601f1061032e57610100808354040283529160200191610359565b820191906000526020600020905b81548152906001019060200180831161033c57829003601f168201915b505050505081565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106103a257805160ff19168380011785556103d0565b828001600101855582156103d0579182015b828111156103cf5782518255916020019190600101906103b4565b5b5090506103dd91906103e1565b5090565b61040391905b808211156103ff5760008160009055506001016103e7565b5090565b9056fea265627a7a7231582049d7f8a29a0126f071821d6483cb3a246925e56555044971726b41b649dd7e6864736f6c63782c302e352e31332d646576656c6f702e323032302e352e31382b636f6d6d69742e33616239633638642e6d6f64005c' +# bytecode = '608060405234801561001057600080fd5b506040516106243803806106248339818101604052602081101561003357600080fd5b810190808051604051939291908464010000000082111561005357600080fd5b8382019150602082018581111561006957600080fd5b825186600182028301116401000000008211171561008657600080fd5b8083526020830192505050908051906020019080838360005b838110156100ba57808201518184015260208101905061009f565b50505050905090810190601f1680156100e75780820380516001836020036101000a031916815260200191505b50604052505050806000908051906020019061010492919061010b565b50506101b0565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061014c57805160ff191683800117855561017a565b8280016001018555821561017a579182015b8281111561017957825182559160200191906001019061015e565b5b509050610187919061018b565b5090565b6101ad91905b808211156101a9576000816000905550600101610191565b5090565b90565b610465806101bf6000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c8063a413686214610046578063cfae321714610101578063ef690cc014610184575b600080fd5b6100ff6004803603602081101561005c57600080fd5b810190808035906020019064010000000081111561007957600080fd5b82018360208201111561008b57600080fd5b803590602001918460018302840111640100000000831117156100ad57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050610207565b005b610109610221565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561014957808201518184015260208101905061012e565b50505050905090810190601f1680156101765780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61018c6102c3565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101cc5780820151818401526020810190506101b1565b50505050905090810190601f1680156101f95780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b806000908051906020019061021d929190610361565b5050565b606060008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156102b95780601f1061028e576101008083540402835291602001916102b9565b820191906000526020600020905b81548152906001019060200180831161029c57829003601f168201915b5050505050905090565b60008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156103595780601f1061032e57610100808354040283529160200191610359565b820191906000526020600020905b81548152906001019060200180831161033c57829003601f168201915b505050505081565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106103a257805160ff19168380011785556103d0565b828001600101855582156103d0579182015b828111156103cf5782518255916020019190600101906103b4565b5b5090506103dd91906103e1565b5090565b61040391905b808211156103ff5760008160009055506001016103e7565b5090565b9056fea265627a7a72315820f67de41e40b8cf679e7bae0565040506f43456684b3fa204030df4e564ea476264736f6c63782c302e352e31332d646576656c6f702e323032302e352e31382b636f6d6d69742e33616239633638642e6d6f64005c' +bytecode = '608060405234801561001057600080fd5b506101a1806100206000396000f3fe6080604052600436106100295760003560e01c80631a6952301461002e578063c84aae1714610072575b600080fd5b6100706004803603602081101561004457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506100d7565b005b34801561007e57600080fd5b506100c16004803603602081101561009557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610121565b6040518082815260200191505060405180910390f35b8073ffffffffffffffffffffffffffffffffffffffff166108fc349081150290604051600060405180830381858888f1935050505015801561011d573d6000803e3d6000fd5b5050565b60008173ffffffffffffffffffffffffffffffffffffffff1631905091905056fea265627a7a723158205ec5e488bb1e8d852f1da0fafa9a4557d3c92d3bf9b839b176c551d75c76b51064736f6c63782c302e352e31332d646576656c6f702e323032302e352e31382b636f6d6d69742e33616239633638642e6d6f64005c' + +# abi = [{"constant":false,"inputs":[],"name":"doWhileControl","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"doWhileControlResult","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"forBreakControl","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"forBreakControlResult","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"forContinueControl","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"forContinueControlResult","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"forControl","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"forControlResult","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"forReturnControl","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"forReturnControlResult","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"int256","name":"age","type":"int256"}],"name":"forThreeControlControl","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"forThreeControlControlResult","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getForBreakControlResult","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getForContinueControlResult","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getForControlResult","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getForReturnControlResult","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getForThreeControlControlResult","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getIfControlResult","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getdoWhileResult","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"age","type":"uint256"}],"name":"ifControl","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"ifControlResult","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"}] +# abi = [{'inputs': [], 'payable': False, 'stateMutability': 'nonpayable', 'type': 'constructor'}, {'constant': True, 'inputs': [], 'name': 'greet', 'outputs': [{'internalType': 'string', 'name': '', 'type': 'string'}], 'payable': False, 'stateMutability': 'view', 'type': 'function'}, {'constant': True, 'inputs': [], 'name': 'greeting', 'outputs': [{'internalType': 'string', 'name': '', 'type': 'string'}], 'payable': False, 'stateMutability': 'view', 'type': 'function'}, {'constant': False, 'inputs': [{'internalType': 'string', 'name': '_greeting', 'type': 'string'}], 'name': 'setGreeting', 'outputs': [], 'payable': False, 'stateMutability': 'nonpayable', 'type': 'function'}] +# abi = [{'inputs': [{'internalType': 'string', 'name': '_greeting', 'type': 'string'}], 'payable': False, 'stateMutability': 'nonpayable', 'type': 'constructor'}, {'constant': True, 'inputs': [], 'name': 'greet', 'outputs': [{'internalType': 'string', 'name': '', 'type': 'string'}], 'payable': False, 'stateMutability': 'view', 'type': 'function'}, {'constant': True, 'inputs': [], 'name': 'greeting', 'outputs': [{'internalType': 'string', 'name': '', 'type': 'string'}], 'payable': False, 'stateMutability': 'view', 'type': 'function'}, {'constant': False, 'inputs': [{'internalType': 'string', 'name': '_greeting', 'type': 'string'}], 'name': 'setGreeting', 'outputs': [], 'payable': False, 'stateMutability': 'nonpayable', 'type': 'function'}] +abi = [{'constant': True, 'inputs': [{'internalType': 'address', 'name': 'addr', 'type': 'address'}], 'name': 'getBalances', 'outputs': [{'internalType': 'uint256', 'name': '', 'type': 'uint256'}], 'payable': False, 'stateMutability': 'view', 'type': 'function'}, {'constant': False, 'inputs': [{'internalType': 'address payable', 'name': 'addr', 'type': 'address'}], 'name': 'transfer', 'outputs': [], 'payable': True, 'stateMutability': 'payable', 'type': 'function'}] + +# Instantiate and deploy contract +Payable = platon.contract(abi=abi, bytecode=bytecode) + +# # Submit the transaction that deploys the contract +# tx_hash = Greeter.constructor().transact() +# +# # Wait for the transaction to be mined, and get the transaction receipt +# tx_receipt = platon.waitForTransactionReceipt(tx_hash) +# print(tx_receipt) +# +# contract_instance = platon.contract(address=contractAddress, abi=abi) +def SendTxn(txn): + signed_txn = platon.account.signTransaction(txn,private_key=send_privatekey) + res = platon.sendRawTransaction(signed_txn.rawTransaction).hex() + txn_receipt = platon.waitForTransactionReceipt(res) + print(res) + return txn_receipt + +txn = Payable.constructor().buildTransaction( + { + 'chainId':200, + 'nonce':platon.getTransactionCount(from_address), + 'gas':1500000, + 'value':0, + 'gasPrice':1000000000, + } +) + +tx_receipt = SendTxn(txn) +print(tx_receipt) + +# Create the contract instance with the newly-deployed address +payable = platon.contract(address=tx_receipt.contractAddress, abi=abi) + +# hrpgot, data = bech32.decode("lax", from_address) +# address = to_checksum_address(bytes(data)) +# print(address) + +# Display the default greeting from the contract +print('Get Address Balance: {}'.format( + payable.functions.getBalances(from_address).call() +)) + +# print('Setting the greeting to Nihao...') +# tx_hash = payable.functions.setGreeting('Nihao').transact( +# { +# 'from':from_address, +# 'gas':1500000, +# } +# ) +# print(tx_hash) +# +# # Wait for transaction to be mined... +# platon.waitForTransactionReceipt(tx_hash) +# +# # Display the new greeting value +# print('Updated contract greeting: {}'.format( +# payable.functions.greet().call() +# )) + +# # When issuing a lot of reads, try this more concise reader: +# reader = ConciseContract(greeter) +# assert reader.greet() == "Nihao" \ No newline at end of file diff --git a/tests/AddressTest.py b/tests/AddressTest.py new file mode 100644 index 0000000..9c39ee2 --- /dev/null +++ b/tests/AddressTest.py @@ -0,0 +1,104 @@ +from client_sdk_python import Web3,HTTPProvider +from client_sdk_python.eth import PlatON + + +# Solidity source code +# contract_source_code = ''' +# pragma solidity ^0.5.0; +# +# contract Payable { +# //获取地址的余额 +# function getBalances(address addr) view public returns (uint){ +# return addr.balance; +# } +# +# function transfer(address payable addr) public payable{ +# addr.transfer(msg.value); +# } +# } +# ''' + +true = True +false = False + +w3 = Web3(HTTPProvider("http://10.1.1.5:6789")) +platon = PlatON(w3) +print(w3.isConnected()) + +from_address = "lax1yjjzvjph3tw4h2quw6mse25y492xy7fzwdtqja" +print(from_address) + +send_privatekey = "b7a7372e78160f71a1a75e03c4aa72705806a05cf14ef39c87fdee93d108588c" + +bytecode = '608060405234801561001057600080fd5b506101a1806100206000396000f3fe6080604052600436106100295760003560e01c80631a6952301461002e578063c84aae1714610072575b600080fd5b6100706004803603602081101561004457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506100d7565b005b34801561007e57600080fd5b506100c16004803603602081101561009557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610121565b6040518082815260200191505060405180910390f35b8073ffffffffffffffffffffffffffffffffffffffff166108fc349081150290604051600060405180830381858888f1935050505015801561011d573d6000803e3d6000fd5b5050565b60008173ffffffffffffffffffffffffffffffffffffffff1631905091905056fea265627a7a723158205ec5e488bb1e8d852f1da0fafa9a4557d3c92d3bf9b839b176c551d75c76b51064736f6c63782c302e352e31332d646576656c6f702e323032302e352e31382b636f6d6d69742e33616239633638642e6d6f64005c' + +abi = [{'constant': True, 'inputs': [{'internalType': 'address', 'name': 'addr', 'type': 'address'}], 'name': 'getBalances', 'outputs': [{'internalType': 'uint256', 'name': '', 'type': 'uint256'}], 'payable': False, 'stateMutability': 'view', 'type': 'function'}, {'constant': False, 'inputs': [{'internalType': 'address payable', 'name': 'addr', 'type': 'address'}], 'name': 'transfer', 'outputs': [], 'payable': True, 'stateMutability': 'payable', 'type': 'function'}] + +# Instantiate and deploy contract +Payable = platon.contract(abi=abi, bytecode=bytecode) + +# # Submit the transaction that deploys the contract +# tx_hash = Greeter.constructor().transact() +# +# # Wait for the transaction to be mined, and get the transaction receipt +# tx_receipt = platon.waitForTransactionReceipt(tx_hash) +# print(tx_receipt) +# +# contract_instance = platon.contract(address=contractAddress, abi=abi) +def SendTxn(txn): + signed_txn = platon.account.signTransaction(txn,private_key=send_privatekey) + res = platon.sendRawTransaction(signed_txn.rawTransaction).hex() + txn_receipt = platon.waitForTransactionReceipt(res) + print(res) + return txn_receipt + +txn = Payable.constructor().buildTransaction( + { + 'chainId':200, + 'nonce':platon.getTransactionCount(from_address), + 'gas':1500000, + 'value':0, + 'gasPrice':1000000000, + } +) + +tx_receipt = SendTxn(txn) +print(tx_receipt) + +# Create the contract instance with the newly-deployed address +payable = platon.contract(address=tx_receipt.contractAddress, abi=abi) + +# hrpgot, data = bech32.decode("lax", from_address) +# address = to_checksum_address(bytes(data)) +# print(address) +address = "lax1yjjzvjph3tw4h2quw6mse25y492xy7fzwdtqja" +# # Display the default greeting from the contract +print('Get Address Balance: {}'.format( + payable.functions.getBalances(from_address).call() +)) +# print('Get Address Balance: {}'.format( +# payable.functions.getBalances(from_address).call() +# )) + +# print('Setting the greeting to Nihao...') +# address1='lax15r7gxd0c9xqxu0vca35wz0zch5qfyayj9ed3r2' +# tx_hash = payable.functions.transfer(address1).transact( +# { +# 'from':from_address, +# 'gas':1500000, +# 'value':10000, +# } +# ) +# print(tx_hash) +# +# # Wait for transaction to be mined... +# platon.waitForTransactionReceipt(tx_hash) +# +# # Display the new greeting value +# print('Updated contract greeting: {}'.format( +# payable.functions.greet().call() +# )) + +# # When issuing a lot of reads, try this more concise reader: +# reader = ConciseContract(greeter) +# assert reader.greet() == "Nihao" \ No newline at end of file diff --git a/tests/EVMContractTest(1).py b/tests/EVMContractTest(1).py new file mode 100644 index 0000000..ce74034 --- /dev/null +++ b/tests/EVMContractTest(1).py @@ -0,0 +1,66 @@ +from hexbytes import HexBytes +from client_sdk_python import Web3, HTTPProvider +from client_sdk_python.eth import PlatON + +true = True +false = False + +w3 = Web3(HTTPProvider("http://10.1.1.5:6789")) +platon = PlatON(w3) +print(w3.isConnected()) + +from_address = "lax1yjjzvjph3tw4h2quw6mse25y492xy7fzwdtqja" +print(from_address) + +send_privatekey = "b7a7372e78160f71a1a75e03c4aa72705806a05cf14ef39c87fdee93d108588c" + +def contract_deploy(bytecode, fromAddress): + bytecode = bytecode + transactionHash = platon.sendTransaction( + { + "from": fromAddress, + "gas": 1000000, + "gasPrice": 1000000000, + "data": bytecode, + } + ) + transactionHash = HexBytes(transactionHash).hex().lower() + return transactionHash + +bytecode = '608060405234801561001057600080fd5b50610c28806100206000396000f3fe608060405234801561001057600080fd5b50600436106101375760003560e01c806357609889116100b85780638e418fdb1161007c5780638e418fdb146104b2578063a64be0d5146104d0578063b4feac7c146104ee578063b87df0141461050c578063c0e641fc1461052a578063da193c1f1461054857610137565b80635760988914610352578063687615d71461037057806371ee52021461038e57806378aa6155146104115780637e6b0f571461042f57610137565b806344e24ce0116100ff57806344e24ce01461029c57806347808fc3146102ca5780634b8016b9146102f8578063508242dc1461031657806356230cca1461033457610137565b80631f9c9f3c1461013c578063275ec9761461015a57806335432d3114610178578063383d49e5146101fb5780633f9dbcf914610219575b600080fd5b610144610566565b6040518082815260200191505060405180910390f35b61016261056c565b6040518082815260200191505060405180910390f35b6101806105ca565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101c05780820151818401526020810190506101a5565b50505050905090810190601f1680156101ed5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610203610668565b6040518082815260200191505060405180910390f35b61022161066e565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610261578082015181840152602081019050610246565b50505050905090810190601f16801561028e5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6102c8600480360360208110156102b257600080fd5b810190808035906020019092919050505061070c565b005b6102f6600480360360208110156102e057600080fd5b8101908080359060200190929190505050610811565b005b6103006108a4565b6040518082815260200191505060405180910390f35b61031e6108aa565b6040518082815260200191505060405180910390f35b61033c6108b0565b6040518082815260200191505060405180910390f35b61035a610907565b6040518082815260200191505060405180910390f35b610378610911565b6040518082815260200191505060405180910390f35b610396610917565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156103d65780820151818401526020810190506103bb565b50505050905090810190601f1680156104035780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6104196109b9565b6040518082815260200191505060405180910390f35b6104376109c3565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561047757808201518184015260208101905061045c565b50505050905090810190601f1680156104a45780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6104ba610a65565b6040518082815260200191505060405180910390f35b6104d8610a9b565b6040518082815260200191505060405180910390f35b6104f6610af2565b6040518082815260200191505060405180910390f35b610514610b30565b6040518082815260200191505060405180910390f35b610532610b3a565b6040518082815260200191505060405180910390f35b610550610b44565b6040518082815260200191505060405180910390f35b60025481565b6000806005819055506000600190505b600a8110156105c05760006005828161059157fe5b0614156105a3576005549150506105c7565b80600560008282540192505081905550808060010191505061057c565b5060055490505b90565b60008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156106605780601f1061063557610100808354040283529160200191610660565b820191906000526020600020905b81548152906001019060200180831161064357829003601f168201915b505050505081565b60035481565b60068054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156107045780601f106106d957610100808354040283529160200191610704565b820191906000526020600020905b8154815290600101906020018083116106e757829003601f168201915b505050505081565b6014811015610766576040518060400160405280601381526020017f796f7520617265206120796f756e67206d616e0000000000000000000000000081525060009080519060200190610760929190610b4e565b5061080e565b603c8110156107c0576040518060400160405280601481526020017f796f75206172652061206d6964646c65206d616e000000000000000000000000815250600090805190602001906107ba929190610b4e565b5061080d565b6040518060400160405280601181526020017f796f75206172652061206f6c64206d616e0000000000000000000000000000008152506000908051906020019061080b929190610b4e565b505b5b50565b60148113610854576040518060400160405280600c81526020017f6d6f7265207468616e203230000000000000000000000000000000000000000081525061088b565b6040518060400160405280600c81526020017f6c657373207468616e20323000000000000000000000000000000000000000008152505b600690805190602001906108a0929190610b4e565b5050565b60045481565b60015481565b60008060048190555060008090505b600a8110156108fe576000600282816108d457fe5b0614156108e0576108f1565b806004600082825401925050819055505b80806001019150506108bf565b50600454905090565b6000600454905090565b60055481565b606060068054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156109af5780601f10610984576101008083540402835291602001916109af565b820191906000526020600020905b81548152906001019060200180831161099257829003601f168201915b5050505050905090565b6000600554905090565b606060008054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610a5b5780601f10610a3057610100808354040283529160200191610a5b565b820191906000526020600020905b815481529060010190602001808311610a3e57829003601f168201915b5050505050905090565b60008060018190555060008090505b80600160008282540192505081905550806001019050600a8110610a745760015491505090565b6000806003819055506000600190505b600a811015610ae957600060028281610ac057fe5b061415610acc57610ae9565b806003600082825401925050819055508080600101915050610aab565b50600354905090565b60008060028190555060008090505b600a811015610b2757806002600082825401925050819055508080600101915050610b01565b50600254905090565b6000600254905090565b6000600354905090565b6000600154905090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10610b8f57805160ff1916838001178555610bbd565b82800160010185558215610bbd579182015b82811115610bbc578251825591602001919060010190610ba1565b5b509050610bca9190610bce565b5090565b610bf091905b80821115610bec576000816000905550600101610bd4565b5090565b9056fea265627a7a7231582003a28b4281af2c524edc05a0c071a68e9f08b99e0a7e70b37dcc181d06a48e6c64736f6c634300050d0032' + +abi = [{"constant":false,"inputs":[],"name":"doWhileControl","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"doWhileControlResult","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"forBreakControl","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"forBreakControlResult","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"forContinueControl","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"forContinueControlResult","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"forControl","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"forControlResult","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"forReturnControl","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"forReturnControlResult","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"int256","name":"age","type":"int256"}],"name":"forThreeControlControl","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"forThreeControlControlResult","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getForBreakControlResult","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getForContinueControlResult","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getForControlResult","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getForReturnControlResult","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getForThreeControlControlResult","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getIfControlResult","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getdoWhileResult","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"age","type":"uint256"}],"name":"ifControl","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"ifControlResult","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"}] +print(type(abi)) + +tx = contract_deploy(bytecode, from_address) +print(tx) +tx_receipt = platon.waitForTransactionReceipt(tx) +print(tx_receipt) +contractAddress = tx_receipt.contractAddress +print(contractAddress) + +def SendTxn(txn): + signed_txn = platon.account.signTransaction(txn,private_key=send_privatekey) + res = platon.sendRawTransaction(signed_txn.rawTransaction).hex() + txn_receipt = platon.waitForTransactionReceipt(res) + print(res) + return txn_receipt + +contract_instance = platon.contract(address=contractAddress, abi=abi) + +txn = contract_instance.functions.ifControl(20).buildTransaction( + { + 'chainId':200, + 'nonce':platon.getTransactionCount(from_address), + 'gas':2000000, + 'value':0, + 'gasPrice':1000000000, + } +) + +print(SendTxn(txn)) + +result = contract_instance.functions.getIfControlResult().call() +print(result) + + diff --git a/tests/EVMContractTest.py b/tests/EVMContractTest.py new file mode 100644 index 0000000..24fa673 --- /dev/null +++ b/tests/EVMContractTest.py @@ -0,0 +1,75 @@ +from hexbytes import HexBytes +from client_sdk_python import Web3, HTTPProvider +from client_sdk_python.eth import PlatON +from client_sdk_python.packages.platon_keys.utils import bech32,address +from client_sdk_python.packages.eth_utils import to_checksum_address + +true = True +false = False + +w3 = Web3(HTTPProvider("http://10.1.1.5:6789")) +platon = PlatON(w3) +print(w3.isConnected()) + +from_address = "lax1yjjzvjph3tw4h2quw6mse25y492xy7fzwdtqja" +print(from_address) + +send_privatekey = "16e80ad4079462cc7f9748af2f9cf03e8f7384bed597c086db4f11a98c3b08f0" + +def contract_deploy(bytecode, fromAddress): + bytecode = bytecode + transactionHash = platon.sendTransaction( + { + "from": fromAddress, + "gas": 1000000, + "gasPrice": 1000000000, + "data": bytecode, + } + ) + transactionHash = HexBytes(transactionHash).hex().lower() + return transactionHash + +bytecode = '608060405234801561001057600080fd5b506040518060400160405280600581526020017f48656c6c6f0000000000000000000000000000000000000000000000000000008152506000908051906020019061005c929190610062565b50610107565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100a357805160ff19168380011785556100d1565b828001600101855582156100d1579182015b828111156100d05782518255916020019190600101906100b5565b5b5090506100de91906100e2565b5090565b61010491905b808211156101005760008160009055506001016100e8565b5090565b90565b610465806101166000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c8063a413686214610046578063cfae321714610101578063ef690cc014610184575b600080fd5b6100ff6004803603602081101561005c57600080fd5b810190808035906020019064010000000081111561007957600080fd5b82018360208201111561008b57600080fd5b803590602001918460018302840111640100000000831117156100ad57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050610207565b005b610109610221565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561014957808201518184015260208101905061012e565b50505050905090810190601f1680156101765780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61018c6102c3565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101cc5780820151818401526020810190506101b1565b50505050905090810190601f1680156101f95780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b806000908051906020019061021d929190610361565b5050565b606060008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156102b95780601f1061028e576101008083540402835291602001916102b9565b820191906000526020600020905b81548152906001019060200180831161029c57829003601f168201915b5050505050905090565b60008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156103595780601f1061032e57610100808354040283529160200191610359565b820191906000526020600020905b81548152906001019060200180831161033c57829003601f168201915b505050505081565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106103a257805160ff19168380011785556103d0565b828001600101855582156103d0579182015b828111156103cf5782518255916020019190600101906103b4565b5b5090506103dd91906103e1565b5090565b61040391905b808211156103ff5760008160009055506001016103e7565b5090565b9056fea265627a7a7231582049d7f8a29a0126f071821d6483cb3a246925e56555044971726b41b649dd7e6864736f6c63782c302e352e31332d646576656c6f702e323032302e352e31382b636f6d6d69742e33616239633638642e6d6f64005c' + +abi = [{"constant":False,"inputs":[],"name":"doWhileControl","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":False,"stateMutability":"nonpayable","type":"function"},{"constant":True,"inputs":[],"name":"doWhileControlResult","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":False,"stateMutability":"view","type":"function"},{"constant":False,"inputs":[],"name":"forBreakControl","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":False,"stateMutability":"nonpayable","type":"function"},{"constant":True,"inputs":[],"name":"forBreakControlResult","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":False,"stateMutability":"view","type":"function"},{"constant":False,"inputs":[],"name":"forContinueControl","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":False,"stateMutability":"nonpayable","type":"function"},{"constant":True,"inputs":[],"name":"forContinueControlResult","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":False,"stateMutability":"view","type":"function"},{"constant":False,"inputs":[],"name":"forControl","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":False,"stateMutability":"nonpayable","type":"function"},{"constant":True,"inputs":[],"name":"forControlResult","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":False,"stateMutability":"view","type":"function"},{"constant":False,"inputs":[],"name":"forReturnControl","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":False,"stateMutability":"nonpayable","type":"function"},{"constant":True,"inputs":[],"name":"forReturnControlResult","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":False,"stateMutability":"view","type":"function"},{"constant":False,"inputs":[{"internalType":"int256","name":"age","type":"int256"}],"name":"forThreeControlControl","outputs":[],"payable":False,"stateMutability":"nonpayable","type":"function"},{"constant":True,"inputs":[],"name":"forThreeControlControlResult","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":False,"stateMutability":"view","type":"function"},{"constant":True,"inputs":[],"name":"getForBreakControlResult","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":False,"stateMutability":"view","type":"function"},{"constant":True,"inputs":[],"name":"getForContinueControlResult","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":False,"stateMutability":"view","type":"function"},{"constant":True,"inputs":[],"name":"getForControlResult","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":False,"stateMutability":"view","type":"function"},{"constant":True,"inputs":[],"name":"getForReturnControlResult","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":False,"stateMutability":"view","type":"function"},{"constant":True,"inputs":[],"name":"getForThreeControlControlResult","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":False,"stateMutability":"view","type":"function"},{"constant":True,"inputs":[],"name":"getIfControlResult","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":False,"stateMutability":"view","type":"function"},{"constant":True,"inputs":[],"name":"getdoWhileResult","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":False,"stateMutability":"view","type":"function"},{"constant":False,"inputs":[{"internalType":"uint256","name":"age","type":"uint256"}],"name":"ifControl","outputs":[],"payable":False,"stateMutability":"nonpayable","type":"function"},{"constant":True,"inputs":[],"name":"ifControlResult","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":False,"stateMutability":"view","type":"function"}] + +tx = contract_deploy(bytecode, from_address) +print(tx) +tx_receipt = platon.waitForTransactionReceipt(tx) +print(tx_receipt) +contractAddress = tx_receipt.contractAddress +print(contractAddress) + +# contractAddress = bech32.bech32_decode(contractAddress) +hrpgot, data = bech32.decode("lax", from_address) +address = to_checksum_address(bytes(data)) +print('qqq') +print(address) + +def SendTxn(txn): + signed_txn = platon.account.signTransaction(txn,private_key=send_privatekey) + res = platon.sendRawTransaction(signed_txn.rawTransaction).hex() + txn_receipt = platon.waitForTransactionReceipt(res) + print(res) + return txn_receipt + + + +# print(len([10, 14, 31, 23, 10, 20, 20, 9, 15, 9, 0, 15, 12, 20, 6, 15, 12, 8, 5, 6, 28, 22, 7, 25, 11, 30, 2, 27, 10, 23, 19, 11])) +contract_instance = platon.contract(address=contractAddress, abi=abi) + +# txn = contract_instance.functions.ifControl(20).buildTransaction( +# { +# 'chainId':200, +# 'nonce':platon.getTransactionCount(from_address), +# 'gas':1000000, +# 'value':0, +# 'gasPrice':1000000000, +# } +# ) +# print("aaaa") +# print(SendTxn(txn)) +# print("bbbb") + +result = contract_instance.functions.getIfControlResult().call() +print(result) \ No newline at end of file diff --git a/tests/GreeterTest.py b/tests/GreeterTest.py new file mode 100644 index 0000000..b5d2fa4 --- /dev/null +++ b/tests/GreeterTest.py @@ -0,0 +1,83 @@ +from client_sdk_python import Web3,HTTPProvider +from client_sdk_python.eth import PlatON +from client_sdk_python.contract import ConciseContract + +# Solidity source code +# contract_source_code = ''' +# pragma solidity ^0.4.21; +# +# contract Greeter { +# string public greeting; +# +# function Greeter() public { +# greeting = 'Hello'; +# } +# +# function setGreeting(string _greeting) public { +# greeting = _greeting; +# } +# +# function greet() view public returns (string) { +# return greeting; +# } +# } +# ''' + +true = True +false = False + +w3 = Web3(HTTPProvider("http://10.1.1.5:6789")) +platon = PlatON(w3) +print(w3.isConnected()) + +from_address = "lax1l0sm6ath520sa8tsq499ya8a5j9qkzh2zxgddm" +print(from_address) + +send_privatekey = "16e80ad4079462cc7f9748af2f9cf03e8f7384bed597c086db4f11a98c3b08f0" + +bytecode = '608060405234801561001057600080fd5b506040518060400160405280600581526020017f48656c6c6f0000000000000000000000000000000000000000000000000000008152506000908051906020019061005c929190610062565b50610107565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100a357805160ff19168380011785556100d1565b828001600101855582156100d1579182015b828111156100d05782518255916020019190600101906100b5565b5b5090506100de91906100e2565b5090565b61010491905b808211156101005760008160009055506001016100e8565b5090565b90565b610465806101166000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c8063a413686214610046578063cfae321714610101578063ef690cc014610184575b600080fd5b6100ff6004803603602081101561005c57600080fd5b810190808035906020019064010000000081111561007957600080fd5b82018360208201111561008b57600080fd5b803590602001918460018302840111640100000000831117156100ad57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050610207565b005b610109610221565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561014957808201518184015260208101905061012e565b50505050905090810190601f1680156101765780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61018c6102c3565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101cc5780820151818401526020810190506101b1565b50505050905090810190601f1680156101f95780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b806000908051906020019061021d929190610361565b5050565b606060008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156102b95780601f1061028e576101008083540402835291602001916102b9565b820191906000526020600020905b81548152906001019060200180831161029c57829003601f168201915b5050505050905090565b60008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156103595780601f1061032e57610100808354040283529160200191610359565b820191906000526020600020905b81548152906001019060200180831161033c57829003601f168201915b505050505081565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106103a257805160ff19168380011785556103d0565b828001600101855582156103d0579182015b828111156103cf5782518255916020019190600101906103b4565b5b5090506103dd91906103e1565b5090565b61040391905b808211156103ff5760008160009055506001016103e7565b5090565b9056fea265627a7a7231582049d7f8a29a0126f071821d6483cb3a246925e56555044971726b41b649dd7e6864736f6c63782c302e352e31332d646576656c6f702e323032302e352e31382b636f6d6d69742e33616239633638642e6d6f64005c' + +# abi = [{"constant":false,"inputs":[],"name":"doWhileControl","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"doWhileControlResult","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"forBreakControl","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"forBreakControlResult","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"forContinueControl","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"forContinueControlResult","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"forControl","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"forControlResult","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"forReturnControl","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"forReturnControlResult","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"int256","name":"age","type":"int256"}],"name":"forThreeControlControl","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"forThreeControlControlResult","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getForBreakControlResult","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getForContinueControlResult","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getForControlResult","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getForReturnControlResult","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getForThreeControlControlResult","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getIfControlResult","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getdoWhileResult","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"age","type":"uint256"}],"name":"ifControl","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"ifControlResult","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"}] +abi = [{'inputs': [], 'payable': False, 'stateMutability': 'nonpayable', 'type': 'constructor'}, {'constant': True, 'inputs': [], 'name': 'greet', 'outputs': [{'internalType': 'string', 'name': '', 'type': 'string'}], 'payable': False, 'stateMutability': 'view', 'type': 'function'}, {'constant': True, 'inputs': [], 'name': 'greeting', 'outputs': [{'internalType': 'string', 'name': '', 'type': 'string'}], 'payable': False, 'stateMutability': 'view', 'type': 'function'}, {'constant': False, 'inputs': [{'internalType': 'string', 'name': '_greeting', 'type': 'string'}], 'name': 'setGreeting', 'outputs': [], 'payable': False, 'stateMutability': 'nonpayable', 'type': 'function'}] +# platon.defaultAccount = platon.accounts[0] +# Instantiate and deploy contract +Greeter = platon.contract(abi=abi, bytecode=bytecode) +print(Greeter) +# Submit the transaction that deploys the contract +tx_hash = Greeter.constructor().transact( + { + 'from':from_address, + 'gas':1500000, + } +) + +# Wait for the transaction to be mined, and get the transaction receipt +tx_receipt = platon.waitForTransactionReceipt(tx_hash) + +# Create the contract instance with the newly-deployed address +greeter = platon.contract(address=tx_receipt.contractAddress, abi=abi) + +# Display the default greeting from the contract +print('Default contract greeting: {}'.format( + greeter.functions.greet().call() +)) + +print('Setting the greeting to Nihao...') +tx_hash = greeter.functions.setGreeting('Nihao').transact( + { + 'from': from_address, + 'gas': 1500000, + } +) + +# Wait for transaction to be mined... +platon.waitForTransactionReceipt(tx_hash) + +# Display the new greeting value +print('Updated contract greeting: {}'.format( + greeter.functions.greet().call() +)) + +# # When issuing a lot of reads, try this more concise reader: +# reader = ConciseContract(greeter) +# assert reader.greet() == "Nihao" \ No newline at end of file diff --git a/tests/JSwasmtest1_input.py b/tests/JSwasmtest1_input.py new file mode 100644 index 0000000..8331635 --- /dev/null +++ b/tests/JSwasmtest1_input.py @@ -0,0 +1,14 @@ +from client_sdk_python.param_encode import rlp_decode,rlp_encode +# input :"0x0061736df9a163b9a1550061736d01000000015c1060027f7f0060017f017f60027f7f017f60017f0060037f7f7f017f60037f7f7f0060047f7f7f7f0060000060047f7f7f7f017f60027f7e0060017f017e60037f7e7e0060037f7e7e017f60017e017f60057f7f7f7f7f006000017f02ce010903656e760c706c61746f6e5f70616e6963000703656e760b706c61746f6e5f73686133000603656e7617706c61746f6e5f6765745f696e7075745f6c656e677468000f03656e7610706c61746f6e5f6765745f696e707574000303656e7617706c61746f6e5f6765745f73746174655f6c656e677468000203656e7610706c61746f6e5f6765745f7374617465000803656e7610706c61746f6e5f7365745f7374617465000603656e760c706c61746f6e5f6576656e74000603656e760d706c61746f6e5f72657475726e000003cd01cb010700020200040000010202020302020500000e000000020001000200010002000001020600020002000200000204000002010102040506000303010400050402050500000104020503010001040c00040b01000004080304000107070704050a0a030103010101010101010d09010000000003000100020100010001010001010a0d09000100000100000201000100010001000001000100010003010001000108030100020100090001030100010100000c0b0208000300000003030105070501010206000600000000000405017001050505030100020608017f0141908c040b073904066d656d6f72790200115f5f7761736d5f63616c6c5f63746f727300090f5f5f66756e63735f6f6e5f65786974006506696e766f6b650063090a010041010b04202124250af0b902cb01050010c7010baa0301097f230041c0016b22022400200241b908100b2104200241e8006a4102100c2103200241d8006a2004100d200241c8006a2000100d200241406b4100360200200241386a4200370300200241306a420037030020024200370328200241286a20022802582204200228025c100e20022802482205200228024c100e210620032002280228100f2003200241d8006a10102003200241c8006a1010200328020c200341106a28020047044010000b2003280204210720032802002108200241106a1011210020024180016a200110122101200241a8016a4100360200200241a0016a420037030020024198016a4200370300200242003703900120024190016a41001013200241b0016a200110121014410110132109200228029001210a200941046a10152000200a100f20004101101620024190016a200110121017220028020c200041106a28020047044010000b20082007200028020020002802041007200028020c22010440200020013602100b200641046a1015200504402002200536024c0b200404402002200436025c0b200328020c22000440200320003602100b200241c0016a24000b910101027f20004200370200200041086a410036020020012102024003402002410371044020022d0000450d02200241016a21020c010b0b2002417c6a21020340200241046a22022802002203417f73200341fffdfb776a7141808182847871450d000b0340200341ff0171450d01200241016a2d00002103200241016a21020c000b000b20002001200220016b105020000b1d0020001051200041146a41003602002000420037020c2000200110160b8b0101037f230041306b22032400200341186a1011220220011052100f2002200341086a200110121017220128020c200141106a28020047044010000b200041003602082000420037020020012802042102200128020021042000412010532004200220002802002202200028020420026b1001200128020c22000440200120003602100b200341306a24000b8b0101017f024020012002460440410121030c010b4101210302400240200220016b2202410146044020012c0000417f4c0d010c030b200241374b0d010b200241016a21030c010b2002105420026a41016a21030b027f200041186a28020022010440200041086a280200200041146a280200200110550c010b20000b2201200128020020036a36020020000b1300200028020820014904402000200110570b0b1600200020012802002200200128020420006b10581a0b190020001051200041146a41003602002000420037020c20000b4d01017f20004200370200200041086a2202410036020020012d0000410171450440200020012902003702002002200141086a28020036020020000f0b200020012802082001280204105020000bc30c02077f027e230041306b22042400200041046a2107027f20014101460440200041086a280200200041146a280200200041186a220228020022031055280200210120022003417f6a3602002007105a4180104f044020072000410c6a280200417c6a105b0b200141384f047f2001105420016a0520010b41016a2102200041186a28020022010440200041086a280200200041146a280200200110550c020b20000c010b02402007105a0d00200041146a28020022014180084f0440200020014180786a360214200041086a2201280200220228020021032001200241046a360200200420033602182007200441186a105c0c010b2000410c6a2802002202200041086a2802006b4102752203200041106a2205280200220620002802046b2201410275490440418020103a2105200220064704400240200028020c220120002802102202470d0020002802082203200028020422064b04402000200320012003200320066b41027541016a417e6d41027422026a105d220136020c2000200028020820026a3602080c010b200441186a200220066b2201410175410120011b22012001410276200041106a105e2102200028020c210320002802082101034020012003470440200228020820012802003602002002200228020841046a360208200141046a21010c010b0b200029020421092000200229020037020420022009370200200029020c21092000200229020837020c200220093702082002105f200028020c21010b200120053602002000200028020c41046a36020c0c020b02402000280208220120002802042202470d00200028020c2203200028021022064904402000200120032003200620036b41027541016a41026d41027422026a106022013602082000200028020c20026a36020c0c010b200441186a200620026b2201410175410120011b2201200141036a410276200041106a105e2102200028020c210320002802082101034020012003470440200228020820012802003602002002200228020841046a360208200141046a21010c010b0b200029020421092000200229020037020420022009370200200029020c21092000200229020837020c200220093702082002105f200028020821010b2001417c6a2005360200200020002802082201417c6a22023602082002280200210220002001360208200420023602182007200441186a105c0c010b20042001410175410120011b20032005105e2102418020103a2106024020022802082201200228020c2203470d0020022802042205200228020022084b04402002200520012005200520086b41027541016a417e6d41027422036a105d22013602082002200228020420036a3602040c010b200441186a200320086b2201410175410120011b22012001410276200241106a280200105e21032002280208210520022802042101034020012005470440200328020820012802003602002003200328020841046a360208200141046a21010c010b0b2002290200210920022003290200370200200320093702002002290208210920022003290208370208200320093702082003105f200228020821010b200120063602002002200228020841046a360208200028020c2105034020002802082005460440200028020421012000200228020036020420022001360200200228020421012002200536020420002001360208200029020c21092000200229020837020c200220093702082002105f052005417c6a210502402002280204220120022802002203470d0020022802082206200228020c22084904402002200120062006200820066b41027541016a41026d41027422036a106022013602042002200228020820036a3602080c010b200441186a200820036b2201410175410120011b2201200141036a4102762002280210105e21062002280208210320022802042101034020012003470440200428022020012802003602002004200428022041046a360220200141046a21010c010b0b20022902002109200220042903183702002002290208210a20022004290320370208200420093703182004200a3703202006105f200228020421010b2001417c6a200528020036020020022002280204417c6a3602040c010b0b0b200441186a20071061200428021c410036020041012102200041186a0b2201200128020020026a360200200441306a240020000ba10101037f41012103024002400240200128020420012d00002202410176200241017122041b220241014d0440200241016b0d032001280208200141016a20041b2c0000417f4c0d010c030b200241374b0d010b200241016a21030c010b2002105420026a41016a21030b027f200041186a28020022010440200041086a280200200041146a280200200110550c010b20000b2201200128020020036a36020020000bea0101047f230041106b22042400200028020422012000280210220241087641fcffff07716a2103027f410020012000280208460d001a2003280200200241ff07714102746a0b2101200441086a20001061200428020c210203400240200120024604402000410036021420002802082103200028020421010340200320016b41027522024103490d022000200141046a22013602040c000b000b200141046a220120032802006b418020470d0120032802042101200341046a21030c010b0b2002417f6a220241014d04402000418004418008200241016b1b3602100b20002001105b200441106a24000b8e0201057f2001044020002802042105200041106a2802002202200041146a280200220349044020022001ad2005ad422086843702002000200028021041086a36021020000f0b027f41002002200028020c22046b410375220641016a2202200320046b2203410275220420042002491b41ffffffff01200341037541ffffffff00491b2204450d001a2004410374103a0b2102200220064103746a22032001ad2005ad4220868437020020032000280210200028020c22066b22016b2105200220044103746a2102200341086a2103200141014e044020052006200110361a0b20002002360214200020033602102000200536020c20000f0b200041c00110d201200041004100410110ce0120000b2c01017f20002001280208200141016a20012d0000220041017122021b2001280204200041017620021b10580bc80301087f230041c0016b22032400200341ac08100b2105200341e8006a4102100c2104200341d8006a2005100d200341c8006a2000100d200341406b4100360200200341386a4200370300200341306a420037030020034200370328200341286a20032802582205200328025c100e20032802482206200328024c100e210720042003280228100f2004200341d8006a10102004200341c8006a1010200428020c200441106a28020047044010000b2004280204210820042802002109200341106a1011210020034180016a200110122101200320023b018c01200341a8016a4100360200200341a0016a420037030020034198016a4200370300200342003703900120034190016a41001013200341b0016a200110121014220220032f018c0110192002410110132102200328029001210a200241046a10152000200a100f20004102101620034190016a200110121017220020032f018c01101a200028020c200041106a28020047044010000b20092008200028020020002802041007200028020c22010440200020013602100b200741046a1015200604402003200636024c0b200504402003200536025c0b200428020c22000440200420003602100b200341c0016a24000b0c0020002001ad420010561a0b0b0020002001ad420010590bf20301067f230041d0016b22052400200541086a419f08100b2107200541f0006a4103100c2106200541e0006a2007100d200541d0006a2000100d200541c8006a4100360200200541406b4200370300200541386a420037030020054200370330200541306a200528026022002005280264100e200528025022072005280254100e22082001101920062005280230100f2006200541e0006a10102006200541d0006a101020062001101a200628020c200641106a28020047044010000b200628020421092006280200210a200541186a1011210120054188016a20021012210220052004360298012005200336029401200541b8016a4100360200200541b0016a4200370300200541a8016a4200370300200542003703a001200541a0016a41001013200541c0016a2002101210142203200528029401101920032005280298011019200341011013210320052802a0012104200341046a101520012004100f200141031016200541a0016a2002101210172201200528029401101a2001200528029801101a200128020c200141106a28020047044010000b200a2009200128020020012802041007200128020c22020440200120023602100b200841046a101520070440200520073602540b20000440200520003602640b200628020c22010440200620013602100b200541d0016a24000b2e01017f230041206b22022400200241106a418d08100b2002419908100b100a200020013a0010200241206a24000b3301017f230041206b22022400200241106a418008100b2002418708100b20011018200041286a20013b0100200241206a24000b3701017f230041206b22022400200241106a418008100b20012002418708100b20012001101b200041406b2001360200200241206a24000b930201047f20002001470440200128020420012d00002202410176200241017122041b2102200141016a210320012802082105410a21012005200320041b210420002d0000410171220304402000280200417e71417f6a21010b200220014d0440027f2003044020002802080c010b200041016a0b21012002044020012004200210490b200120026a41003a000020002d000041017104402000200236020420000f0b200020024101743a000020000f0b416f2103200141e6ffffff074d0440410b20014101742201200220022001491b220141106a4170712001410b491b21030b2003103a22012004200210c801200020023602042000200341017236020020002001360208200120026a41003a00000b20000b0d00200041b0016a20013a00000b0b00200041b0016a2c00000b230020002001101f1a2000410c6a2001410c6a101f1a200041186a200141186a101f1a0b25002000200110121a2000410c6a2001410c6a10121a200041186a200141186a10121a20000b0d00200041c8026a20013a00000b0b00200041c8026a2c00000b9e0101047f2000200147044020012802042203200128020022026b41017522042000280208200028020022016b4101754d0440200041046a21052004200028020420016b41017522004b04402002200220004101746a22002001104e1a20002003200510460f0b2005200220032001104e3602000f0b2001044020004100360208200042003702000b200020002004104f104c20022003200041046a10460b0b3e01017f2000420037020020004100360208200128020420012802006b2202044020002002410175104c20012802002001280204200041046a10460b20000b3001027f200141046a21032001280200210203402002200346044020004188046a20011029052002102a21020c010b0b0be00201067f230041206b22042400024020002001460d00200141046a21062001280200210102402000280208450d00200028020021032000200041046a3602002000410036020820002802042102200041003602042002410036020820032802042202200320021b2102034020022203450d0120012006470440200341106a200141106a101f21072003411c6a2001411c6a101f1a024020032802082202450440410021020c010b2003200228020022054604402002410036020020022802042205450d012005104321020c010b200241003602042005450d002005104321020b2000200441106a2007104421072000200428021020072003103f2001102a21010c010b0b0340200328020822030d000b200621010b034020012006460d01200441106a2000200141106a104a20002004410c6a2004280210220341106a104421022000200428020c20022003103f2001102a21010c000b000b200441206a24000b3601017f024020002802042201044003402001220028020022010d000c020b000b0340200020002802082200280200470d000b0b20000bd60101067f230041106b22022400200042003702042000200041046a2203360200200141046a21062001280200210103402001200646450440200141106a21050240027f027f0240024020032000280200460440200321040c010b2003103b220441106a2005103c450d010b20032802004504402002200336020c2003210420030c030b2002200436020c200441046a0c010b20002002410c6a2005103d0b22042802000d01200228020c0b2107200220002005104a2000200720042002280200103f0b2001102a21010c010b0b200241106a240020000b2300200041d0016a2001101f1a20004198016a20033a0000200041f8026a20023602000b920101047f2000200147044020012802042203200128020022026b22042000280208200028020022016b4d0440200041046a21052004200028020420016b22004b04402002200020026a2200200110471a20002003200510460f0b200520022003200110473602000f0b2001044020004100360208200042003702000b2000200020041048104520022003200041046a10460b0b3b01017f2000420037020020004100360208200128020420012802006b2202044020002002104520012802002001280204200041046a10460b20000b2601017f0340200241f800470440200020026a200120026a101f1a2002410c6a21020c010b0b0b2301017f0340200020026a200120026a10121a2002410c6a220241f800470d000b20000b130020002001101f1a2000200128020c36020c0b15002000200110121a2000200128020c36020c20000b3001027f200141046a210320012802002102034020022003460440200041f8066a20011034052002102a21020c010b0b0bd30201067f230041206b22042400024020002001460d00200141046a21062001280200210102402000280208450d00200028020021032000200041046a3602002000410036020820002802042102200041003602042002410036020820032802042202200320021b2102034020022203450d0120012006470440200341106a200141106a101f2107024020032802082202450440410021020c010b2003200228020022054604402002410036020020022802042205450d012005104321020c010b200241003602042005450d002005104321020b2000200441106a2007104421072000200428021020072003103f2001102a21010c010b0b0340200328020822030d000b200621010b034020012006460d01200441106a2000200141106a103e20002004410c6a2004280210220341106a104421022000200428020c20022003103f2001102a21010c000b000b200441206a24000bd60101067f230041106b22022400200042003702042000200041046a2203360200200141046a21062001280200210103402001200646450440200141106a21050240027f027f0240024020032000280200460440200321040c010b2003103b220441106a2005103c450d010b20032802004504402002200336020c2003210420030c030b2002200436020c200441046a0c010b20002002410c6a2005103d0b22042802000d01200228020c0b2107200220002005103e2000200720042002280200103f0b2001102a21010c010b0b200241106a240020000bfc0801067f03400240200020046a2105200120046a210320022004460d002003410371450d00200520032d00003a0000200441016a21040c010b0b200220046b210602402005410371220745044003402006411049450440200020046a2203200120046a2205290200370200200341086a200541086a290200370200200441106a2104200641706a21060c010b0b027f2006410871450440200120046a2103200020046a0c010b200020046a2205200120046a2204290200370200200441086a2103200541086a0b21042006410471044020042003280200360200200341046a2103200441046a21040b20064102710440200420032f00003b0000200341026a2103200441026a21040b2006410171450d01200420032d00003a000020000f0b024020064120490d002007417f6a220741024b0d00024002400240024002400240200741016b0e020102000b2005200120046a220328020022073a0000200541016a200341016a2f00003b0000200041036a2108200220046b417d6a2106034020064111490d03200420086a2203200120046a220541046a2802002202410874200741187672360200200341046a200541086a2802002207410874200241187672360200200341086a2005410c6a28020022024108742007411876723602002003410c6a200541106a2802002207410874200241187672360200200441106a2104200641706a21060c000b000b2005200120046a220328020022073a0000200541016a200341016a2d00003a0000200041026a2108200220046b417e6a2106034020064112490d03200420086a2203200120046a220541046a2802002202411074200741107672360200200341046a200541086a2802002207411074200241107672360200200341086a2005410c6a28020022024110742007411076723602002003410c6a200541106a2802002207411074200241107672360200200441106a2104200641706a21060c000b000b2005200120046a28020022073a0000200041016a21082004417f7320026a2106034020064113490d03200420086a2203200120046a220541046a2802002202411874200741087672360200200341046a200541086a2802002207411874200241087672360200200341086a2005410c6a28020022024118742007410876723602002003410c6a200541106a2802002207411874200241087672360200200441106a2104200641706a21060c000b000b200120046a41036a2103200020046a41036a21050c020b200120046a41026a2103200020046a41026a21050c010b200120046a41016a2103200020046a41016a21050b20064110710440200520032d00003a00002005200328000136000120052003290005370005200520032f000d3b000d200520032d000f3a000f200541106a2105200341106a21030b2006410871044020052003290000370000200541086a2105200341086a21030b2006410471044020052003280000360000200541046a2105200341046a21030b20064102710440200520032f00003b0000200541026a2105200341026a21030b2006410171450d00200520032d00003a00000b20000b2b01027f200141046a210203402002280200220341046a210220012003470d000b200041a80b6a200110380bbe0201057f024020002001460d00200041046a2102200141046a21030340200228020021020240027f4101200328020022032001460d001a20002002470d0141000b210402402000200246044020040d044114103a22054100360200200541086a200341086a10121a20052104410121060340200120032802042203460d024114103a220241086a200341086a10121a2002200436020020042002360204200641016a2106200221040c000b000b200228020022032000280200220128020436020420012802042003360200034020002002460d0420002000280208417f6a360208200228020421020c000b000b2000280200220220053602042005200236020020002004360200200420003602042000200028020820066a3602080c020b200241086a200341086a101f1a200241046a2102200341046a21030c000b000b0b840101037f200041003602082000200036020420002000360200200141046a2102037f20022802002203200146047f2000054114103a22024100360200200241086a200341086a10121a20022000360204200028020021042000200236020020022004360200200420023602042000200028020841016a360208200341046a21020c010b0b0b0b002000410120001b10620b3e01027f024020002802002201044003402001220228020422010d000c020b000b03402000280208220228020020004621012002210020010d000b0b20020bb20101067f02400240200128020420012d00002202410176200241017122031b2205200028020420002d00002202410176200241017122041b2206200520064922071b2202450d002000280208200041016a20041b21002001280208200141016a20031b210103402002450d0120002d0000220320012d00002204460440200141016a2101200041016a21002002417f6a21020c010b0b200320046b22020d010b417f200720062005491b21020b2002411f760b890101027f200041046a2103024020002802042200044002400340024002402002200041106a2204103c0440200028020022040d012001200036020020000f0b20042002103c450d03200041046a210320002802042204450d01200321000b20002103200421000c010b0b2001200036020020030f0b200120003602000c010b200120033602000b20030b2d01017f2000411c103a22033602002000200141046a360204200341106a200210121a200041086a41013a00000b480020032001360208200342003702002002200336020020002802002802002201044020002001360200200228020021030b2000280204200310402000200028020841016a3602080bec0101037f200120002001463a000c03400240024020002001460d00200128020822022d000c0d002002200228020822032802002204460440024020032802042204450d0020042d000c0d002004410c6a21010c030b20012002280200470440200210412002280208220228020821030b200241013a000c200341003a000c200310420f0b02402004450d0020042d000c0d002004410c6a21010c020b20012002280200460440200210422002280208220228020821030b200241013a000c200341003a000c200310410b0f0b200241013a000c200320002003463a000c200141013a0000200321010c000b000b5101027f200020002802042201280200220236020420020440200220003602080b200120002802083602082000280208220220022802002000474102746a200136020020002001360208200120003602000b5101027f200020002802002201280204220236020020020440200220003602080b200120002802083602082000280208220220022802002000474102746a200136020020002001360208200120003602040b1d01017f03402000220128020022000d00200128020422000d000b20010b5c01017f0240200028020422030440034002402002200341106a103c044020032802002200450d040c010b200328020422000d0020012003360200200341046a0f0b200021030c000b000b200041046a21030b2001200336020020030b2001017f20002001103a2202360200200020023602042000200120026a3602080b2800200120006b220141014e044020022802002000200110361a2002200228020020016a3602000b0b1900200120006b2201044020022000200110490b200120026a0b2e01017f2001200028020820002802006b2200410174220220022001491b41ffffffff07200041ffffffff03491b0b8d0301037f024020002001460d00200120006b20026b410020024101746b4d044020002001200210361a0c010b20002001734103712103027f024020002001490440200020030d021a410021030340200120036a2105200020036a2204410371450440200220036b210241002103034020024104490d04200320046a200320056a280200360200200341046a21032002417c6a21020c000b000b20022003460d04200420052d00003a0000200341016a21030c000b000b024020030d002001417f6a21040340200020026a22034103714504402001417c6a21032000417c6a2104034020024104490d03200220046a200220036a2802003602002002417c6a21020c000b000b2002450d042003417f6a200220046a2d00003a00002002417f6a21020c000b000b2001417f6a210103402002450d03200020026a417f6a200120026a2d00003a00002002417f6a21020c000b000b200320056a2101200320046a0b210303402002450d01200320012d00003a00002002417f6a2102200341016a2103200141016a21010c000b000b0b2c01017f20004128103a22033602002000200141046a360204200341106a2002104b200041086a41013a00000b16002000200110121a2000410c6a2001410c6a10121a0b2301017f20002001104d2202360200200020023602042000200220014101746a3602080b09002000410174103a0b2501017f200120006b220141017521032001044020022000200110490b200220034101746a0b2a002001200028020820002802006b220020002001491b41ffffffff07200041017541ffffffff03491b0b5b01027f02402002410a4d0440200020024101743a0000200041016a21030c010b200241106a4170712204103a21032000200236020420002004410172360200200020033602080b20032001200210c801200220036a41003a00000b160020004100360208200042003702002000410010570b5801027f230041306b22012400200141286a4100360200200141206a4200370300200141186a420037030020014200370310200141106a2001200010121014210020012802102102200041046a1015200141306a240020020bdd0101047f024020002802042203200028020022026b22042001490440200028020820036b200120046b22024f04400340200341003a00002000200028020441016a22033602042002417f6a22020d000c030b000b200020011048220104402001103a21050b200420056a220421030340200341003a0000200341016a21032002417f6a22020d000b200120056a210520042000280204200028020022046b22016b2102200141014e044020022004200110361a0b2000200536020820002003360204200020023602000f0b200420014d0d002000200120026a3602040b0b1e01017f03402000044020004108762100200141016a21010c010b0b20010b25002000200120026a417f6a220241087641fcffff07716a280200200241ff07714102746a0b900101027f4101210420014280015441002002501b450440034020012002845045044020024238862001420888842101200341016a2103200242088821020c010b0b200341384f047f2003105420036a0520030b41016a21040b027f200041186a28020022030440200041086a280200200041146a280200200310550c010b20000b2203200328020020046a36020020000b2f01017f2000280208200149044020011062200028020020002802041036210220002001360208200020023602000b0b7001017f4101210302400240024002402002410146044020012c000022024100480d012000200241ff017110d2010c040b200241374b0d01200221030b200020034180017341ff017110d2010c010b2000200210d301200221030b200020012003410010ce010b2000410110d00120000bcf0202037f027e02402001200284500440200041800110d2010c010b20014280015441002002501b4504402001210720022106034020062007845045044020064238862007420888842107200341016a2103200642088821060c010b0b0240200341384f04402003210403402004044020044108762104200541016a21050c010b0b200541c9004f044010000b2000200541b77f6a41ff017110d2012000200028020420056a10d101200028020420002802006a417f6a21052003210403402004450d02200520043a0000200441087621042005417f6a21050c000b000b200020034180017341ff017110d2010b2000200028020420036a10d101200028020420002802006a417f6a210303402001200284500d02200320013c0000200242388620014208888421012003417f6a2103200242088821020c000b000b20002001a741ff017110d2010b2000410110d0010b2801017f200028020820002802046b2201410874417f6a410020011b200028021420002802106a6b0b2501017f200028020821020340200120024645044020002002417c6a22023602080c010b0b0ba10202057f017e230041206b22052400024020002802082202200028020c2203470d0020002802042204200028020022064b04402000200420022004200420066b41027541016a417e6d41027422036a105d22023602082000200028020420036a3602040c010b200541086a200320066b2202410175410120021b220220024102762000410c6a105e2103200028020821042000280204210203402002200446450440200328020820022802003602002003200328020841046a360208200241046a21020c010b0b2000290200210720002003290200370200200320073702002000290208210720002003290208370208200320073702082003105f200028020821020b200220012802003602002000200028020841046a360208200541206a24000b2501017f200120006b220141027521032001044020022000200110490b200220034102746a0b4f01017f2000410036020c200041106a2003360200200104402001410274103a21040b200020043602002000200420024102746a22023602082000200420014102746a36020c2000200236020420000b2b01027f200028020821012000280204210203402001200247044020002001417c6a22013602080c010b0b0b1b00200120006b22010440200220016b22022000200110490b20020b4f01037f20012802042203200128021020012802146a220441087641fcffff07716a21022000027f410020032001280208460d001a2002280200200441ff07714102746a0b360204200020023602000b9b0101047f230041106b220124002001200036020c2000047f41880c200041086a2202411076220041880c2802006a220336020041840c41840c280200220420026a41076a417871220236020002400240200341107420024d044041880c200341016a360200200041016a21000c010b2000450d010b200040000d0010000b20042001410c6a4104103641086a0541000b2100200141106a240020000b090010c701106410650bc52602057f027e230041c0166b2201240010022200106222021003200141d00a6a200141086a20022000106622004100106702400240200141d00a6a10682205500d0041c208106920055104402000106a200141d00a6a106b106c0c020b41c708106920055104402000106d410247044010000b200141d00a6a200041011067200141d00a6a106e2100200141d00a6a106b22022000101c2002106c0c020b41d008106920055104402000106a200141d00a6a106b22032d00102102200141b8086a101122002002106f100f20002002101a200028020c200041106a28020047044010000b200028020020002802041008200028020c22020440200020023602100b2003106c0c020b41d908106920055104402000106d410247044010000b200141d00a6a200041011067200141d00a6a10702100200141d00a6a106b22022000101d2002106c0c020b41e308106920055104402000106a200141d00a6a106b220341286a2f01002102200141b8086a1011220020021071100f20002002101a200028020c200041106a28020047044010000b200028020020002802041008200028020c22020440200020023602100b2003106c0c020b41ed08106920055104402000106d410247044010000b200141d00a6a200041011067200141d00a6a10722100200141d00a6a106b22022000101e2002106c0c020b41f708106920055104402000106a200141d00a6a106b220341406b2802002102200141b8086a1011220020021073100f20002002101a200028020c200041106a28020047044010000b200028020020002802041008200028020c22020440200020023602100b2003106c0c020b418109106920055104402000106d410247044010000b200141d00a6a200041011067200141d00a6a10682105200141d00a6a106b220041d8006a20053703002000106c0c020b418b09106920055104402000106a200141d00a6a106b220241d8006a2903002105200141b8086a1011220020051074100f200020051075200028020c200041106a28020047044010000b200028020020002802041008200028020c22030440200020033602100b2002106c0c020b41950910692005510440200141b8066a107621022000106d410247044010000b200141d00a6a200041011067200141d00a6a20021077200141d00a6a106b220041f8006a200141b8086a20021012101f1a2000106c0c020b419f09106920055104402000106a200141a0046a200141d00a6a106b220241f8006a10122100200141b8086a1011220320001052100f2003200141b8066a200010121017220028020c200041106a28020047044010000b200028020020002802041008200028020c22030440200020033602100b2002106c0c020b41a90910692005510440200141003a00b8082000106d410247044010000b200141d00a6a200041011067200141d00a6a200141b8086a1078200141d00a6a106b22004198016a20012d00b8083a00002000106c0c020b41b109106920055104402000106a200141d00a6a106b22034198016a2d00002102200141b8086a101122002002106f100f20002002101a200028020c200041106a28020047044010000b200028020020002802041008200028020c22020440200020023602100b2003106c0c020b41b909106920055104402000410110790c020b41c1091069200551044020004102107a0c020b41c90910692005510440200141b8066a107b2000106d410247044010000b200141d00a6a200041011067200141d00a6a200141b8066a107c200141d00a6a106b220041d0016a200141b8086a200141b8066a1012101f1a2000106c0c020b41d409106920055104402000106a200141b8066a200141d00a6a106b220241d0016a10121a200141b8086a10112200200141b8066a107d100f2000200141b8066a107e200028020c200041106a28020047044010000b200028020020002802041008200028020c22030440200020033602100b2002106c0c020b41df0910692005510440200141b8066a4124107f1a200141b8066a10800121022000106d410247044010000b200141d00a6a200041011067200141d00a6a2002108101200141d00a6a106b22004190026a200141b8086a2002102310222000106c0c020b41ec09106920055104402000106a200141b8086a200141d00a6a106b22034190026a10232102200141b8066a101122002002108201100f20002002108301200028020c200041106a28020047044010000b200028020020002802041008200028020c22020440200020023602100b2003106c0c020b41f909106920055104402000410310790c020b41810a1069200551044020004104107a0c020b41890a106920055104402000106d410247044010000b200141d00a6a200041011067200141d00a6a1084012100200141d00a6a106b220241e0026a20003b01002002106c0c020b41920a106920055104402000106a200141d00a6a106b220341e0026a2e01002102200141b8086a101122002002108501100f20002002108601200028020c200041106a28020047044010000b200028020020002802041008200028020c22020440200020023602100b2003106c0c020b419b0a106920055104402000106d410247044010000b200141d00a6a200041011067200141d00a6a1087012100200141d00a6a106b220241f8026a20003602002002106c0c020b41a40a106920055104402000106a200141d00a6a106b220341f8026a2802002102200141b8086a101122002002108801100f20002002108601200028020c200041106a28020047044010000b200028020020002802041008200028020c22020440200020023602100b2003106c0c020b41ad0a106920055104402000106d410247044010000b200141d00a6a200041011067200141d00a6a1089012105200141d00a6a106b22004190036a20053703002000106c0c020b41b60a106920055104402000106a200141d00a6a106b22024190036a2903002105200141b8086a101122002005108a01100f20002005108b01200028020c200041106a28020047044010000b200028020020002802041008200028020c22030440200020033602100b2002106c0c020b41bf0a10692005510440200141003602c006200142003703b8062000106d410247044010000b200141d00a6a200041011067200141d00a6a200141b8066a108c01200141d00a6a106b220241e0036a200141b8086a200141b8066a102722001026200028020022030440200020033602040b2002106c20012802b8062200450d02200120003602bc060c020b41c90a106920055104402000106a200141b8066a200141d00a6a106b220341e0036a10272102200141b8086a101122002002108d01100f20002002108e01200028020c200041106a28020047044010000b200028020020002802041008200028020c22040440200020043602100b200228020022000440200220003602040b2003106c0c020b41d30a10692005510440200142003702bc062001200141b8066a4104723602b8062000106d410247044010000b200141d00a6a200041011067200141d00a6a200141b8066a108f01200141d00a6a106b2200200141b8086a200141b8066a102b10282000106c0c020b41da0a106920055104402000106a200141b8066a200141d00a6a106b22034188046a102b2102200141b8086a101122002002109001100f20002002109101200028020c200041106a28020047044010000b200028020020002802041008200028020c22020440200020023602100b2003106c0c020b41e10a10692005510440200141b8086a107b200141003a00c808200141003602c408200141c8086a21022000106d410447044010000b200141d00a6a200041011067200141d00a6a200141b8086a107c200141d00a6a2000410210672001200141d00a6a1087013602c408200141d00a6a200041031067200141d00a6a20021078200141d00a6a106b2100200141b8066a200141b8086a10121a2000200141b8066a20012802c40820012d00c808102c2000106c0c020b41f10a10692005510440200141003602a804200142003703a0042000106d410247044010000b200141d00a6a200041011067200141d00a6a200141a0046a109201200141d00a6a106b220341b0046a200141b8086a200141b8066a200141a0046a102e2200102e2202102d200228020022040440200220043602040b200028020022020440200020023602040b2003106c20012802a0042200450d02200120003602a4040c020b41fa0a106920055104402000106a200141b8066a200141d00a6a106b220341b0046a102e2102200141b8086a1011220020022802002002280204109301100f200020021010200028020c200041106a28020047044010000b200028020020002802041008200028020c22040440200020043602100b200228020022000440200220003602040b2003106c0c020b41830b10692005510440200141b8066a41f800107f1a200141b8066a10940121022000106d410247044010000b200141d00a6a200041011067200141d00a6a2002109501200141d00a6a106b220041c0056a200141b8086a20021030102f2000106c0c020b418c0b106920055104402000106a200141b8086a200141d00a6a106b220341c0056a10302102200141b8066a101122002002109601100f20002002109701200028020c200041106a28020047044010000b200028020020002802041008200028020c22020440200020023602100b2003106c0c020b41950b10692005510440200141b8066a10980121022000106d410247044010000b200141d00a6a200041011067200141d00a6a2002109901200141d00a6a106b220041d0066a200141b8086a2002103210312000106c0c020b419d0b106920055104402000106a200141b8066a200141d00a6a106b220341d0066a10322102200141b8086a101122002002109a01100f20002002109b01200028020c200041106a28020047044010000b200028020020002802041008200028020c22020440200020023602100b2003106c0c020b41a50b10692005510440200142003702bc062001200141b8066a4104723602b8062000106d410247044010000b200141d00a6a200041011067200141d00a6a200141b8066a109c01200141d00a6a106b2200200141b8086a200141b8066a103510332000106c0c020b41ac0b106920055104402000106a200141b8066a200141d00a6a106b220341f8066a10352102200141b8086a101122002002109d01100f20002002109e01200028020c200041106a28020047044010000b200028020020002802041008200028020c22020440200020023602100b2003106c0c020b41b30b10692005510440200141b8066a109f0121022000106d410247044010000b200141d00a6a200041011067200141d00a6a200210a001200141d00a6a106b2100200141206a200141b8066a41800210361a200141b8086a200141206a41800210361a20004190096a200141b8086a41800210361a2000106c0c020b41c00b106920055104402000106a200141a0026a200141d00a6a106b22024190096a41800210361a200141a0066a10112200200141a0026a10a101100f200141a0046a200141a0026a41800210361a200141b8066a200141a0046a41800210361a200141206a200141b8066a41800210361a200141b8086a200141206a41800210361a2000200141b8086a4180021058220028020c200041106a28020047044010000b200028020020002802041008200028020c22030440200020033602100b2002106c0c020b41cd0b10692005510440200141003602c0062001200141b8066a3602bc062001200141b8066a3602b8062000106d410247044010000b200141d00a6a200041011067200141d00a6a200141b8066a10a201200141d00a6a106b2200200141b8086a200141b8066a103922021037200210a3012000106c200141b8066a10a3010c020b41d50b106920055104402000106a200141b8066a200141d00a6a106b220341a80b6a10392102200141b8086a10112200200210a401100f2000200210a501200028020c200041106a28020047044010000b200028020020002802041008200028020c22040440200020043602100b200210a3012003106c0c020b41dd0b10692005510440200141b8086a10a60121022000106d410247044010000b200141d00a6a200041011067200141d00a6a200210a701200141d00a6a106b2100200141b0066a200141c8086a2802002202360200200141a8066a200141c0086a2903002205370300200120012903b80822063703a006200041d80b6a2006370300200041e00b6a2005370300200041e80b6a20023602002000106c0c020b41e80b10692005520d002000106a200141306a2200200141d00a6a106b220241e80b6a280000360200200141286a2203200241e00b6a2900003703002001200241d80b6a290000370320200141b8086a10112204200141206a10a801100f200141b0026a20002802002200360200200141a8026a200329030022053703002001200129032022063703a002200141a8046a2005370300200141b0046a2000360200200141a8066a2005370300200141b0066a2000360200200120063703a004200120063703a006200141c8066a2000360200200141c0066a2005370300200120063703b8062004200141b8066a41141058220028020c200041106a28020047044010000b200028020020002802041008200028020c22030440200020033602100b2002106c0c010b10000b200141c0166a24000b880101037f41f40b410136020041f80b2802002100034020000440034041fc0b41fc0b2802002201417f6a2202360200200141014845044041f40b4100360200200020024102746a22004184016a280200200041046a28020011030041f40b410136020041f80b28020021000c010b0b41fc0b412036020041f80b200028020022003602000c010b0b0b0d00200020012002411c10a9010bd00202067f017e230041106b220324002001280208220520024b0440200341086a200110cd0120012003280208200328020c10cb0136020c2003200110cd01410021052001027f410020032802002207450d001a410020032802042208200128020c2206490d001a200820062006417f461b210420070b360210200141146a2004360200200141003602080b200141106a210603402001280214210402402005200249044020040d01410021040b200020062802002004411410a9011a200341106a24000f0b2003200110cd0141002104027f410020032802002205450d001a410020032802042208200128020c2207490d001a200820076b2104200520076a0b210520012004360214200120053602102003200641002005200410cb0110cc012001200329030022093702102001200128020c2009422088a76a36020c2001200128020841016a22053602080c000b000b880102027f017e230041106b22012400200010aa0102400240200010ab01450d002000280204450d0020002802002d000041c001490d010b10000b200141086a200010ac01200128020c220041094f044010000b200128020821020340200004402000417f6a210020023100002003420886842103200241016a21020c010b0b200141106a240020030b3901027e42a5c688a1c89ca7f94b210103402000300000220250450440200041016a2100200142b383808080207e20028521010c010b0b20010b0e002000106d410147044010000b0bca2901097f230041406a22012400200042ddbe888dc5fcfca4987f370308200041003a0000200141286a1011220320002903081075200328020c200341106a28020047044010000b0240200328020022072003280204220810042205450d002001410036022020014200370318200141186a200510532007200820012802182204200128021c220620046b1005417f47044020002001200441016a20062004417f736a1066106e3a0010200521020b2004450d002001200436021c0b200328020c22040440200320043602100b2002450440200020002d00003a00100b41002102200041003b0118200041206a220442debe888dc5fcfca4987f370300200141286a1011220320042903001075200328020c200341106a28020047044010000b0240200328020022072003280204220810042205450d002001410036022020014200370318200141186a200510532007200820012802182204200128021c220620046b1005417f47044020002001200441016a20062004417f736a106610703b0128200521020b2004450d002001200436021c0b200328020c22040440200320043602100b2002450440200020002f01183b01280b4100210220004100360230200041386a220442dfbe888dc5fcfca4987f370300200141286a1011220320042903001075200328020c200341106a28020047044010000b0240200328020022072003280204220810042205450d002001410036022020014200370318200141186a200510532007200820012802182204200128021c220620046b1005417f47044020002001200441016a20062004417f736a10661072360240200521020b2004450d002001200436021c0b200328020c22040440200320043602100b2002450440200020002802303602400b20004200370348200041d0006a220242d9be888dc5fcfca4987f370300200141286a1011220320022903001075200328020c200341106a28020047044010000b0240200328020022072003280204220810042205450440410021040c010b410021042001410036022020014200370318200141186a200510532007200820012802182202200128021c220620026b1005417f47044020002001200241016a20062002417f736a10661068370358200521040b2002450d002001200236021c0b200328020c22020440200320023602100b2004450440200020002903483703580b200041e0006a10762109200041f0006a220242a7cea8ad82a0ff995b370300200041f8006a10762107200141286a1011220320022903001075200328020c200341106a28020047044010000b0240200328020022082003280204220610042205450440410021040c010b410021042001410036022020014200370318200141186a200510532008200620012802182202200128021c220620026b1005417f4704402001200241016a20062002417f736a106620071077200521040b2002450d002001200236021c0b200328020c22020440200320023602100b200445044020072009101f1a0b41002102200041003a00880120004190016a220442f4a2efb3f6e5b8ad03370300200141286a1011220320042903001075200328020c200341106a28020047044010000b0240200328020022072003280204220810042205450d002001410036022020014200370318200141186a200510532007200820012802182204200128021c220620046b1005417f4704402001200441016a20062004417f736a106620004198016a1078200521020b2004450d002001200436021c0b200328020c22040440200320043602100b2002450440200020002d0088013a0098010b200041003a00a001200041a8016a220342badda0b2f6c5fa8e033703002003200041b0016a10ad01450440200020002d00a0013a00b0010b200042003703b801200041c0016a4100360200200041b8016a10762109200041c8016a2202428aedabfdf7a698fe29370300200041d0016a220710761a200141286a1011220320022903001075200328020c200341106a28020047044010000b0240200328020022082003280204220610042205450440410021040c010b410021042001410036022020014200370318200141186a200510532008200620012802182202200128021c220620026b1005417f4704402001200241016a20062002417f736a10662007107c200521040b2002450d002001200236021c0b200328020c22020440200320023602100b200445044020072009101f1a0b41002102200041e0016a4124107f108001210920004188026a220442d4b7b1edebf7e3f66a37030020004190026a1080012107200141286a1011220320042903001075200328020c200341106a28020047044010000b0240200328020022082003280204220610042205450d002001410036022020014200370318200141186a200510532008200620012802182204200128021c220620046b1005417f4704402001200441016a20062004417f736a10662007108101200521020b2004450d002001200436021c0b200328020c22040440200320043602100b20024504402007200910220b200041003a00b802200041c0026a220342ccacbdb4f8a587a93d3703002003200041c8026a10ad01450440200020002d00b8023a00c8020b200041003b01d002200041d8026a220242cfacbdb4f8a587a93d370300200141286a1011220320022903001075200328020c200341106a28020047044010000b0240200328020022072003280204220810042205450440410021040c010b410021042001410036022020014200370318200141186a200510532007200820012802182202200128021c220620026b1005417f47044020002001200241016a20062002417f736a10661084013b01e002200521040b2002450d002001200236021c0b200328020c22020440200320023602100b2004450440200020002f01d0023b01e0020b41002102200041003602e802200041f0026a220442ceacbdb4f8a587a93d370300200141286a1011220320042903001075200328020c200341106a28020047044010000b0240200328020022072003280204220810042205450d002001410036022020014200370318200141186a200510532007200820012802182204200128021c220620046b1005417f47044020002001200441016a20062004417f736a10661087013602f802200521020b2004450d002001200436021c0b200328020c22040440200320043602100b2002450440200020002802e8023602f8020b200042003703800320004188036a220242c8acbdb4f8a587a93d370300200141286a1011220320022903001075200328020c200341106a28020047044010000b0240200328020022072003280204220810042205450440410021040c010b410021042001410036022020014200370318200141186a200510532007200820012802182202200128021c220620026b1005417f47044020002001200241016a20062002417f736a106610890137039003200521040b2002450d002001200236021c0b200328020c22020440200320023602100b20044504402000200029038003370390030b410021022000410036029803200041a0036a220442e2e780dbeae4fcabe100370300200141286a1011220320042903001075200328020c200341106a28020047044010000b0240200328020022072003280204220810042205450d002001410036022020014200370318200141186a200510532007200820012802182204200128021c220620046b1005417f47044020002001200441016a20062004417f736a106610723602a803200521020b2004450d002001200436021c0b200328020c22040440200320043602100b200245044020002000280298033602a8030b200042003703b003200041b8036a220242b3debf9dbddf9ca832370300200141286a1011220320022903001075200328020c200341106a28020047044010000b0240200328020022072003280204220810042205450440410021040c010b410021042001410036022020014200370318200141186a200510532007200820012802182202200128021c220620026b1005417f47044020002001200241016a20062002417f736a106610683703c003200521040b2002450d002001200236021c0b200328020c22020440200320023602100b2004450440200020002903b0033703c0030b200042003702c80341002102200041e8036a4100360200200041e0036a22074200370200200041d8036a2204429fe6c89bc186c5be1d370300200041d0036a4100360200200141286a1011220320042903001075200328020c200341106a28020047044010000b0240200328020022082003280204220610042205450d002001410036022020014200370318200141186a200510532008200620012802182204200128021c220920046b1005417f4704402001200441016a20092004417f736a10662007108c01200521020b2004450d002001200436021c0b200328020c22040440200320043602100b20024504402007200041c8036a10260b200041f4036a220342003702002000418c046a2202420037020020004180046a2204428cbcadf0bacdb08975370300200020033602f00320004188046a22072002360200200141286a1011220320042903001075200328020c200341106a28020047044010000b0240200328020022082003280204220610042205450440410021040c010b410021042001410036022020014200370318200141186a200510532008200620012802182202200128021c220920026b1005417f4704402001200241016a20092002417f736a10662007108f01200521040b2002450d002001200236021c0b200328020c22020440200320023602100b20044504402007200041f0036a10290b200042003702980441002102200041b8046a4100360200200041b0046a22074200370200200041a8046a220442bd8ce2969cacfba4b07f370300200041a0046a4100360200200141286a1011220320042903001075200328020c200341106a28020047044010000b0240200328020022082003280204220610042205450d002001410036022020014200370318200141186a200510532008200620012802182204200128021c220920046b1005417f4704402001200441016a20092004417f736a10662007109201200521020b2004450d002001200436021c0b200328020c22040440200320043602100b2002450440200720004198046a102d0b41002102200041c0046a41f800107f1094012109200041b8056a2204429fa88ce0a0829ecea47f370300200041c0056a1094012107200141286a1011220320042903001075200328020c200341106a28020047044010000b0240200328020022082003280204220610042205450d002001410036022020014200370318200141186a200510532008200620012802182204200128021c220620046b1005417f4704402001200441016a20062004417f736a10662007109501200521020b2004450d002001200436021c0b200328020c22040440200320043602100b200245044020072009102f0b200041b8066a1098012109200041c8066a220242bcf8d4f484c7a18d807f370300200041d0066a1098012107200141286a1011220320022903001075200328020c200341106a28020047044010000b0240200328020022082003280204220610042205450440410021040c010b410021042001410036022020014200370318200141186a200510532008200620012802182202200128021c220620026b1005417f4704402001200241016a20062002417f736a10662007109901200521040b2002450d002001200236021c0b200328020c22020440200320023602100b20044504402007200910310b200041e4066a22034200370200200041fc066a22024200370200200041f0066a220442eafdbbb690ac81edca00370300200020033602e006200041f8066a22072002360200200141286a1011220320042903001075200328020c200341106a28020047044010000b0240200328020022082003280204220610042205450440410021040c010b410021042001410036022020014200370318200141186a200510532008200620012802182202200128021c220920026b1005417f4704402001200241016a20092002417f736a10662007109c01200521040b2002450d002001200236021c0b200328020c22020440200320023602100b20044504402007200041e0066a10340b20004188076a2209109f011a20004188096a220242d0b4afbcbf988ce0b77f37030020004190096a109f012107200141286a1011220320022903001075200328020c200341106a28020047044010000b0240200328020022082003280204220610042205450440410021040c010b410021042001410036022020014200370318200141186a200510532008200620012802182202200128021c220620026b1005417f4704402001200241016a20062002417f736a1066200710a001200521040b2002450d002001200236021c0b200328020c22020440200320023602100b20044504402007200941800210361a0b41002104200041b00b6a4100360200200041ac0b6a200041a80b6a2202360200200041a00b6a220542f4ffce959b97c9c1d500370300200041980b6a4100360200200041940b6a200041900b6a2207360200200020073602900b20022002360200200141286a1011220320052903001075200328020c200341106a28020047044010000b0240200328020022062003280204220910042208450d002001410036022020014200370318200141186a200810532006200920012802182205200128021c220620056b1005417f4704402001200541016a20062005417f736a1066200210a201200821040b2005450d002001200536021c0b200328020c22050440200320053602100b20044504402002200710380b200041b80b6a220710a6011a200041d00b6a220242affad78bbfdecaa6f300370300200041d80b6a10a6012104200141286a1011220320022903001075200328020c200341106a28020047044010000b0240200328020022062003280204220910042208450440410021050c010b410021052001410036022020014200370318200141186a200810532006200920012802182202200128021c220620026b1005417f4704402001200241016a20062002417f736a1066200410a701200821050b2002450d002001200236021c0b200328020c22020440200320023602100b200545044020042007290300370300200441106a200741106a280200360200200441086a200741086a2903003703000b200141406b240020000b953102087f027e230041c0086b22052400200541c0066a10112201200041d00b6a22022903001074100f200120022903001075200041d80b6a2102200128020c200141106a28020047044010000b2001280204210720012802002106200541c0046a10112104200210a8012108200420054180026a10ae01220310af012004200820032802046a20032802006b100f200541a0026a200241106a280000220836020020054198026a200241086a290000220937030020052002290000220a37039002200541b0026a2009370300200541b8026a2008360200200541086a2009370300200541106a20083602002005200a3703a8022005200a370300200541d0026a2008360200200541c8026a20093703002005200a3703c00202402004200541c0026a41141058220228020c200241106a280200460440200241046a2104200228020021080c010b200241046a2104100020022802002108200228020c2002280210460d0010000b20062007200820042802001006200328020022040440200320043602040b200228020c22030440200220033602100b200128020c22020440200120023602100b200541c0066a10112202200041a00b6a22012903001074100f200220012903001075200041a80b6a2104200228020c200241106a28020047044010000b2002280204210820022802002107200541c0046a10112101200410a40121062001200541c0026a10ae01220310af012001200620032802046a20032802006b100f2001200410a5010240200128020c200141106a280200460440200141046a2104200128020021060c010b200141046a2104100020012802002106200128020c2001280210460d0010000b20072008200620042802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200041a80b6a10a301200041900b6a10a301200541a8026a1011220120004188096a22022903001074100f20012002290300107520004190096a2104200128020c200141106a28020047044010000b200128020421082001280200210720054190026a10112102200410a1012106200220054180026a10ae01220310af012002200620032802046a20032802006b100f200520044180021036220541c0026a200541800210361a200541c0046a200541c0026a41800210361a200541c0066a200541c0046a41800210361a02402002200541c0066a4180021058220228020c200241106a280200460440200241046a2104200228020021060c010b200241046a2104100020022802002106200228020c2002280210460d0010000b20072008200620042802001006200328020022040440200320043602040b200228020c22030440200220033602100b200128020c22020440200120023602100b200541c0066a10112202200041f0066a22012903001074100f200220012903001075200041f8066a2104200228020c200241106a28020047044010000b2002280204210820022802002107200541c0046a101121012004109d0121062001200541c0026a10ae01220310af012001200620032802046a20032802006b100f20012004109e010240200128020c200141106a280200460440200141046a2104200128020021060c010b200141046a2104100020012802002106200128020c2001280210460d0010000b20072008200620042802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a10112202200041c8066a22012903001074100f200220012903001075200041d0066a2104200228020c200241106a28020047044010000b2002280204210820022802002107200541c0046a101121012004109a0121062001200541c0026a10ae01220310af012001200620032802046a20032802006b100f20012004109b010240200128020c200141106a280200460440200141046a2104200128020021060c010b200141046a2104100020012802002106200128020c2001280210460d0010000b20072008200620042802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a10112202200041b8056a22012903001074100f200220012903001075200041c0056a2104200228020c200241106a28020047044010000b2002280204210820022802002107200541c0046a10112101200410960121062001200541c0026a10ae01220310af012001200620032802046a20032802006b100f200120041097010240200128020c200141106a280200460440200141046a2104200128020021060c010b200141046a2104100020012802002106200128020c2001280210460d0010000b20072008200620042802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a10112202200041a8046a22012903001074100f200220012903001075200041b0046a2104200228020c200241106a28020047044010000b2002280204210820022802002107200541c0046a1011210120002802b004200041b4046a28020010930121062001200541c0026a10ae01220310af012001200620032802046a20032802006b100f2001200410100240200128020c200141106a280200460440200141046a2104200128020021060c010b200141046a2104100020012802002106200128020c2001280210460d0010000b20072008200620042802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200041b0046a28020022010440200041b4046a20013602000b200028029804220104402000419c046a20013602000b200541c0066a1011220220004180046a22012903001074100f20022001290300107520004188046a2104200228020c200241106a28020047044010000b2002280204210820022802002107200541c0046a10112101200410900121062001200541c0026a10ae01220310af012001200620032802046a20032802006b100f200120041091010240200128020c200141106a280200460440200141046a2104200128020021060c010b200141046a2104100020012802002106200128020c2001280210460d0010000b20072008200620042802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a10112202200041d8036a22012903001074100f200220012903001075200041e0036a2104200228020c200241106a28020047044010000b2002280204210820022802002107200541c0046a101121012004108d0121062001200541c0026a10ae01220310af012001200620032802046a20032802006b100f20012004108e010240200128020c200141106a280200460440200141046a2104200128020021060c010b200141046a2104100020012802002106200128020c2001280210460d0010000b20072008200620042802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200041e0036a28020022010440200041e4036a20013602000b20002802c80322010440200041cc036a20013602000b200541c0046a10112202200041b8036a22012903001074100f200220012903001075200228020c200241106a28020047044010000b2002280204210420022802002108200541c0026a10112101200541d8066a4100360200200541d0066a4200370300200541c8066a4200370300200542003703c006200541c0066a20002903c00310b00120052802c0062107200541c0066a41047210152001200541c0066a10ae01220310af012001200720032802046a20032802006b100f200120002903c00310750240200128020c200141106a280200460440200141046a2107200128020021060c010b200141046a2107100020012802002106200128020c2001280210460d0010000b20082004200620072802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0046a10112202200041a0036a22012903001074100f200220012903001075200228020c200241106a28020047044010000b2002280204210420022802002108200541c0026a10112101200541d8066a4100360200200541d0066a4200370300200541c8066a4200370300200542003703c006200541c0066a20002802a803101920052802c0062107200541c0066a41047210152001200541c0066a10ae01220310af012001200720032802046a20032802006b100f200120002802a803101a0240200128020c200141106a280200460440200141046a2107200128020021060c010b200141046a2107100020012802002106200128020c2001280210460d0010000b20082004200620072802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a1011220220004188036a22012903001074100f200220012903001075200228020c200241106a28020047044010000b2002280204210420022802002108200541c0046a10112101200029039003108a0121072001200541c0026a10ae01220310af012001200720032802046a20032802006b100f2001200029039003108b010240200128020c200141106a280200460440200141046a2107200128020021060c010b200141046a2107100020012802002106200128020c2001280210460d0010000b20082004200620072802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a10112202200041f0026a22012903001074100f200220012903001075200228020c200241106a28020047044010000b2002280204210420022802002108200541c0046a1011210120002802f80210880121072001200541c0026a10ae01220310af012001200720032802046a20032802006b100f200120002802f8021086010240200128020c200141106a280200460440200141046a2107200128020021060c010b200141046a2107100020012802002106200128020c2001280210460d0010000b20082004200620072802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a10112202200041d8026a22012903001074100f200220012903001075200228020c200241106a28020047044010000b2002280204210420022802002108200541c0046a1011210120002f01e00210850121072001200541c0026a10ae01220310af012001200720032802046a20032802006b100f200120002e01e0021086010240200128020c200141106a280200460440200141046a2107200128020021060c010b200141046a2107100020012802002106200128020c2001280210460d0010000b20082004200620072802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200041c0026a200041c8026a10b101200541c0066a1011220220004188026a22012903001074100f20022001290300107520004190026a2104200228020c200241106a28020047044010000b2002280204210820022802002107200541c0046a10112101200410820121062001200541c0026a10ae01220310af012001200620032802046a20032802006b100f200120041083010240200128020c200141106a280200460440200141046a2104200128020021060c010b200141046a2104100020012802002106200128020c2001280210460d0010000b20072008200620042802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a10112202200041c8016a22012903001074100f200220012903001075200041d0016a2104200228020c200241106a28020047044010000b2002280204210820022802002107200541c0046a101121012004107d21062001200541c0026a10ae01220310af012001200620032802046a20032802006b100f20012004107e0240200128020c200141106a280200460440200141046a2104200128020021060c010b200141046a2104100020012802002106200128020c2001280210460d0010000b20072008200620042802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200041a8016a200041b0016a10b101200541c0066a1011220220004190016a22012903001074100f200220012903001075200228020c200241106a28020047044010000b2002280204210420022802002108200541c0046a1011210120002d009801106f21072001200541c0026a10ae01220310af012001200720032802046a20032802006b100f200120002d009801101a0240200128020c200141106a280200460440200141046a2107200128020021060c010b200141046a2107100020012802002106200128020c2001280210460d0010000b20082004200620072802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a10112201200041f0006a22022903001074100f200120022903001075200041f8006a2104200128020c200141106a28020047044010000b2001280204210820012802002107200541c0046a101121022004105221062002200541c0026a10ae01220310af012002200620032802046a20032802006b100f024020022005200410121017220228020c200241106a280200460440200241046a2104200228020021060c010b200241046a2104100020022802002106200228020c2002280210460d0010000b20072008200620042802001006200328020022040440200320043602040b200228020c22030440200220033602100b200128020c22020440200120023602100b200541c0066a10112202200041d0006a22012903001074100f200220012903001075200228020c200241106a28020047044010000b2002280204210420022802002108200541c0046a101121012000290358107421072001200541c0026a10ae01220310af012001200720032802046a20032802006b100f2001200029035810750240200128020c200141106a280200460440200141046a2107200128020021060c010b200141046a2107100020012802002106200128020c2001280210460d0010000b20082004200620072802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a10112202200041386a22012903001074100f200220012903001075200228020c200241106a28020047044010000b2002280204210420022802002108200541c0046a101121012000280240107321072001200541c0026a10ae01220310af012001200720032802046a20032802006b100f20012000280240101a0240200128020c200141106a280200460440200141046a2107200128020021060c010b200141046a2107100020012802002106200128020c2001280210460d0010000b20082004200620072802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a10112202200041206a22012903001074100f200220012903001075200228020c200241106a28020047044010000b2002280204210420022802002108200541c0046a1011210120002f0128107121072001200541c0026a10ae01220310af012001200720032802046a20032802006b100f200120002f0128101a0240200128020c200141106a280200460440200141046a2107200128020021060c010b200141046a2107100020012802002106200128020c2001280210460d0010000b20082004200620072802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a1011220220002903081074100f200220002903081075200228020c200241106a28020047044010000b2002280204210420022802002108200541c0046a1011210120002d0010106f21072001200541c0026a10ae01220310af012001200720032802046a20032802006b100f200120002d0010101a0240200128020c200141106a280200460440200141046a2107200128020021060c010b200141046a2107100020012802002106200128020c2001280210460d0010000b20082004200620072802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0086a24000b2601017f02402000280204450d0020002802002d000041c001490d00200010b20121010b20010b800101037f230041106b22012400200010aa0102400240200010ab01450d002000280204450d0020002802002d000041c001490d010b10000b200141086a200010ac01200128020c220041024f044010000b200128020821020340200004402000417f6a210020022d00002103200241016a21020c010b0b200141106a240020030b5801027f230041206b22012400200141186a4100360200200141106a4200370300200141086a42003703002001420037030020012000ad42ff018342001056210020012802002102200041046a1015200141206a240020020b8b0101037f230041106b22012400200010aa0102400240200010ab01450d002000280204450d0020002802002d000041c001490d010b10000b200141086a200010ac01200128020c220041034f044010000b200128020821030340200004402000417f6a210020032d00002002410874722102200341016a21030c010b0b200141106a2400200241ffff03710b5401017f230041206b22012400200141186a4100360200200141106a4200370300200141086a4200370300200142003703002001200041ffff037110192001280200210020014104721015200141206a240020000b860101037f230041106b22012400200010aa0102400240200010ab01450d002000280204450d0020002802002d000041c001490d010b10000b200141086a200010ac01200128020c220041054f044010000b200128020821030340200004402000417f6a210020032d00002002410874722102200341016a21030c010b0b200141106a240020020b4f01017f230041206b22012400200141186a4100360200200141106a4200370300200141086a4200370300200142003703002001200010192001280200210020014104721015200141206a240020000b5001027f230041206b22012400200141186a4100360200200141106a4200370300200141086a4200370300200142003703002001200010b0012001280200210220014104721015200141206a240020020b0a0020002001420010590b1a0020004200370200200041086a4100360200200010b30120000ba40201057f230041206b22022400024002402000280204044020002802002d000041c001490d010b200241086a10761a0c010b200241186a200010ac01200010b40121030240024002400240200228021822000440200228021c220520034f0d010b41002100200241106a410036020020024200370308410021050c010b200241106a4100360200200242003703082000200520032003417f461b22046a21052004410a4b0d010b200220044101743a0008200241086a41017221030c010b200441106a4170712206103a21032002200436020c20022006410172360208200220033602100b03402000200546450440200320002d00003a0000200341016a2103200041016a21000c010b0b200341003a00000b2001200241086a10b501200241206a24000b0e0020012000106e4100473a00000b4401027f230041f00b6b220224002000106d410247044010000b2002200041011067200210b60121002002106b21032002200020011100002003106c200241f00b6a24000b7b01027f230041900c6b220224002000106a200241086a106b2103200241086a20011101002100200241f80b6a10112201200010b701100f20012000108601200128020c200141106a28020047044010000b200128020020012802041008200128020c22000440200120003602100b2003106c200241900c6a24000b180020004200370200200041086a4100360200200010761a0b2801017f230041206b22022400200241086a200041001067200241086a20011077200241206a24000b5001017f230041206b22012400200141186a4100360200200141106a4200370300200141086a4200370300200142003703002001200010b8012001280200210020014104721015200141206a240020000b6e01027f230041406a220224002000410110162100200241386a4100360200200241306a4200370300200241286a420037030020024200370320200241206a200241106a200110121014210320002002280220100f200020022001101210171a200341046a1015200241406b24000be10201027f02402001450d00200041003a0000200020016a2203417f6a41003a000020014103490d00200041003a0002200041003a00012003417d6a41003a00002003417e6a41003a000020014107490d00200041003a00032003417c6a41003a000020014109490d002000410020006b41037122026a220341003602002003200120026b417c7122026a2201417c6a410036020020024109490d002003410036020820034100360204200141786a4100360200200141746a410036020020024119490d002003410036021820034100360214200341003602102003410036020c200141706a41003602002001416c6a4100360200200141686a4100360200200141646a41003602002002200341047141187222026b2101200220036a2102034020014120490d0120024200370300200241186a4200370300200241106a4200370300200241086a4200370300200241206a2102200141606a21010c000b000b20000b1900200010761a2000410c6a10761a200041186a10761a20000b5601017f230041206b22022400200241086a200041001067200241086a2001107c200241086a200041011067200241086a2001410c6a1077200241086a200041021067200241086a200141186a1077200241206a24000b7a01027f230041406a22012400200141186a4100360200200141106a4200370300200141086a4200370300200142003703002001410010132202200010b8012002200141306a2000410c6a10121014200141206a200041186a1012101441011013210020012802002102200041046a1015200141406b240020020ba30101047f230041e0006b220224002000410310162100200241d8006a4100360200200241d0006a4200370300200241c8006a420037030020024200370340200241406b200110b801200241406b200241306a2001410c6a220310121014200241206a200141186a220410121014210520002002280240100f20002001107e2000200241106a20031012101720022004101210171a200541046a1015200241e0006a24000b3902017f017e230041106b220124002001200010b90120012903002102200141106a2400420020024201837d200242018885a74110744110750b6202027f017e230041206b22012400200141186a4100360200200141106a4200370300200141086a42003703002001420037030020012000ad42308622034230872003423f8710ba01210020012802002102200041046a1015200141206a240020020b1301017e20002001ac22022002423f8710bb010b3302017f017e230041106b220124002001200010b90120012903002102200141106a2400420020024201837d200242018885a70b5201027f230041206b22012400200141186a4100360200200141106a4200370300200141086a4200370300200142003703002001200010bc01210020012802002102200041046a1015200141206a240020020b4202017f027e230041106b220124002001200010b901200141086a290300210320012903002102200141106a2400420020024201837d2003423f86200242018884850b5701037f230041206b22012400200141186a4100360200200141106a4200370300200141086a420037030020014200370300200120002000423f8710ba01210220012802002103200241046a1015200141206a240020030b0e00200020012001423f8710bb010bb10201047f230041d0006b22022400024002402000280204450d0020002802002d000041c001490d002000106d21032001280208200128020022046b4101752003490440200120022003200128020420046b410175200141086a10bd01220310be01200310bf010b200241286a200010c001200241186a200010c101200141086a21050340200228022c200228021c46044020022802302002280220460d030b2002200241286a10c2012002107021030240200128020422002001280208490440200020033b01002001200041026a3602040c010b200241386a2001200020012802006b410175220041016a104f2000200510bd0121002002280240220420033b01002002200441026a3602402001200010be01200010bf010b200241286a10c3010c000b000b10000b200241d0006a24000b9c0101037f230041206b22012400200141186a4100360200200141106a4200370300200141086a420037030020014200370300024020002802002000280204460440200110c4010c010b200141001013210220002802042103200028020021000340200020034604402002410110131a05200220002f01001019200041026a21000c010b0b0b2001280200210020014104721015200141206a240020000b4301017f2000200128020420012802006b410175101621022001280204210020012802002101034020002001470440200220012f0100101a200141026a21010c010b0b0be20201057f23004190016b22022400024002402000280204450d0020002802002d000041c001490d00200241c8006a200010c001200241386a200010c101200241146a21040340200228024c200228023c46044020022802502002280240460d030b200241206a200241c8006a10c201200241086a10762100200410762105200241206a10c501410247044010000b20024180016a10762103200241e8006a200241206a41001067200241e8006a200310772000200310b501200241d8006a10762103200241e8006a200241206a41011067200241e8006a200310772005200310b5012001200241e8006a2000103d22062802004504404128103a22032002290308370210200341186a200241106a280200360200200010b301200341246a200441086a2802003602002003411c6a2004290200370200200510b3012001200228026820062003103f0b200241c8006a10c3010c000b000b10000b20024190016a24000bd00101047f230041e0006b22012400200141206a4100360200200141186a4200370300200141106a42003703002001420037030802402000280208450440200141086a10c4010c010b200041046a2103200141086a410010132102200141346a2104200028020021000340200020034604402002410110131a05200141286a200041106a104b200241001013200141d0006a200141286a10121014200141406b200410121014410110131a2000102a21000c010b0b0b20012802082100200141086a4104721015200141e0006a240020000b6101027f230041206b220224002000200128020810162103200141046a210020012802002101034020002001460440200241206a240005200341021016200241106a200141106a1012101720022001411c6a101210171a2001102a21010c010b0b0bce0101037f230041206b22022400024002402000280204044020002802002d000041c001490d010b20024100360208200242003703000c010b200241186a200010ac0120022802182103200241106a200010ac0120022802102104200010b40121002002410036020820024200370300200020046a20036b2200450d0020022000104520004101480d002002200228020420032000103620006a3602040b2001280200044020014100360208200142003702000b2001200228020036020020012002290204370204200241206a24000b5301017f230041206b22022400200241186a4100360200200241106a4200370300200241086a420037030020024200370300200220002001100e210020022802002101200041046a1015200241206a240020010b2c01037f200041f8006a21022000210103402001107621032001410c6a21012003410c6a2002470d000b20000b6101037f230041306b22022400200010c501410a47044010000b03402003410a460440200241306a240005200241206a10762104200241086a200020031067200241086a200410772001200410b5012001410c6a2101200341016a21030c010b0b0b800101037f230041306b22012400200141186a4100360200200141106a4200370300200141086a42003703002001420037030020014100101321030340200241f800464504402003200141206a200020026a101210141a2002410c6a21020c010b0b200341011013210220012802002103200241046a1015200141306a240020030b4401027f230041106b220224002000410a10162103410021000340200041f800460440200241106a24000520032002200020016a101210171a2000410c6a21000c010b0b0b1000200010761a2000410036020c20000b5d01027f230041306b22022400200010c501410247044010000b200241206a10762103200241086a200041001067200241086a200310772001200310b501200241086a2000410110672001200241086a10870136020c200241306a24000b7301027f230041406a22012400200141286a4100360200200141206a4200370300200141186a4200370300200142003703102001200010322100200141106a41001013200141306a200010121014200028020c10bc0141011013210020012802102102200041046a1015200141406b240020020b2a01017f230041106b220224002000410210162002200110121017200128020c108601200241106a24000bd70101047f230041d0006b22022400024002402000280204450d0020002802002d000041c001490d00200241406b200010c001200241306a200010c101200241106a210403402002280244200228023446044020022802482002280238460d030b200241186a200241406b10c201200241186a200241086a1076220010772001200241cc006a2000103d2205280200450440411c103a22032002290308370210200341186a2004280200360200200010b3012001200228024c20052003103f0b200241406b10c3010c000b000b10000b200241d0006a24000b9e0101037f230041306b22012400200141186a4100360200200141106a4200370300200141086a42003703002001420037030002402000280208450440200110c4010c010b200041046a21032001410010132102200028020021000340200020034604402002410110131a052002200141206a200041106a101210141a2000102a21000c010b0b0b2001280200210020014104721015200141306a240020000b4f01027f230041106b220224002000200128020810162103200141046a210020012802002101034020002001460440200241106a24000520032002200141106a101210171a2001102a21010c010b0b0b2601017f0340200141800246450440200020016a41003a0000200141016a21010c010b0b20000b990101027f23004190046b22022400200010aa0120024188046a200010ac01200228028c042103024002402000280204450d0020034180024b0d0020002802002d000041c001490d010b10000b20024188026a109f0120034180022003418002491b22006b4180026a200228028804200010361a200241086a20024188026a41800210361a2001200241086a41800210361a20024190046a24000bc00101037f230041a0086b2201240020014198026a410036020020014190026a420037030020014188026a42003703002001420037038002200120004180021036220041a0026a200041800210361a200041a0046a200041a0026a41800210361a200041a0066a200041a0046a41800210361a41012103024003402002418002460d01200041a0066a20026a2101200241016a210220012d0000450d000b41830221030b200020033602800220004180026a4104721015200041a0086a240020030bec0101037f230041d0006b22022400024002402000280204450d0020002802002d000041c001490d00200241406b200010c001200241306a200010c101200241106a210403402002280244200228023446044020022802482002280238460d030b200241186a200241406b10c201200241186a200241086a1076220310774114103a2200410036020020002002290308370208200041106a2004280200360200200310b30120002001360204200128020021032001200036020020002003360200200320003602042001200128020841016a360208200241406b10c3010c000b000b10000b200241d0006a24000b4d01037f02402000280208450d00200028020422012802002202200028020022032802043602042000410036020820032802042002360200034020002001460d01200128020421010c000b000b0b9d0101037f230041306b22012400200141186a4100360200200141106a4200370300200141086a42003703002001420037030002402000280208450440200110c4010c010b200041046a2102200141001013210303402002280200220220004604402003410110131a052003200141206a200241086a101210141a200241046a21020c010b0b0b2001280200210220014104721015200141306a240020020b4e01027f230041106b22032400200141046a210220002001280208101621000340200228020022022001460440200341106a24000520002003200241086a101210171a200241046a21020c010b0b0b2501017f03402001411446450440200020016a41003a0000200141016a21010c010b0b20000bbe0102027f027e230041406a22022400200010aa01200241386a200010ac01200228023c2103024002402000280204450d00200341144b0d0020002802002d000041c001490d010b10000b200241206a10a6012003411420034114491b22006b41146a2002280238200010361a200241186a200241306a2802002200360200200241106a200241286a2903002204370300200220022903202205370308200141106a2000360000200141086a200437000020012005370000200241406b24000b850202037f027e23004180016b22012400200141306a4100360200200141286a4200370300200141206a4200370300200141086a200041086a2900002204370300200141106a200041106a280000220236020020014200370318200120002900002205370300200141406b2004370300200141c8006a2002360200200141d8006a2004370300200141e0006a20023602002001200537033820012005370350200141f8006a2002360200200141f0006a200437030020012005370368410121020240034020034114460d01200141e8006a20036a2100200341016a210320002d0000450d000b411521020b20012002360218200141186a410472101520014180016a240020020b750020004200370210200042ffffffff0f370208200020023602042000200136020002402003410871450d00200010c90120024f0d002003410471044010000c010b200042003702000b02402003411071450d00200010c90120024d0d0020034104710440100020000f0b200042003702000b20000b4101017f200028020445044010000b0240200028020022012d0000418101470d00200028020441014d047f100020002802000520010b2c00014100480d0010000b0b990101037f200028020445044041000f0b200010aa01200028020022022c0000220141004e044020014100470f0b027f4101200141807f460d001a200141ff0171220341b7014d0440200028020441014d047f100020002802000520020b2d00014100470f0b4100200341bf014b0d001a2000280204200141ff017141ca7e6a22014d047f100020002802000520020b20016a2d00004100470b0bd60101047f200110b4012204200128020422024b04401000200128020421020b200128020021052000027f02400240200204404100210120052c00002203417f4a0d01027f200341ff0171220141bf014d04404100200341ff017141b801490d011a200141c97e6a0c010b4100200341ff017141f801490d001a200141897e6a0b41016a21010c010b4101210120050d000c010b41002103200120046a20024b0d0020022001490d00410020022004490d011a200120056a2103200220016b20042004417f461b0c010b41000b360204200020033602000bc20101057f230041406a22022400200241286a1011220320002903001075200328020c200341106a28020047044010000b02402003280200220020032802042205100422064504400c010b2002410036022020024200370318200241186a200610532000200520022802182200200228021c220520006b1005417f47044020012002200041016a20052000417f736a106610b6013a0000200621040b2000450d002002200036021c0b200328020c22000440200320003602100b200241406b240020040b30002000410036020820004200370200200041011045200028020441fe013a00002000200028020441016a36020420000b6101037f200028020c200041106a28020047044010000b200028020422022001280204200128020022036b22016a220420002802084b047f20002004105720002802040520020b20002802006a2003200110361a2000200028020420016a3602040b0b0020002001420010561a0b8e0201067f230041406a22042400200441286a1011220220002903001074100f200220002903001075200228020c200241106a28020047044010000b2002280204210620022802002107200441106a1011210020012d000010b70121052000200410ae01220310af012000200520032802046a20032802006b100f200020012c00001086010240200028020c200041106a280200460440200041046a2101200028020021050c010b200041046a2101100020002802002105200028020c2000280210460d0010000b20072006200520012802001006200328020022010440200320013602040b200028020c22030440200020033602100b200228020c22000440200220003602100b200441406b24000b820101047f230041106b2201240002402000280204450d0020002802002d000041c001490d00200141086a200010cd01200128020c210003402000450d0120014100200128020822032003200010cb0122046a20034520002004497222031b3602084100200020046b20031b2100200241016a21020c000b000b200141106a240020020b2201017f03402001410c470440200020016a4100360200200141046a21010c010b0b0b800301037f200028020445044041000f0b200010aa0141012102024020002802002c00002201417f4a0d00200141ff0171220341b7014d0440200341807f6a0f0b02400240200141ff0171220141bf014d0440024020002802042201200341c97e6a22024d047f100020002802040520010b4102490d0020002802002d00010d0010000b200241054f044010000b20002802002d000145044010000b4100210241b7012101034020012003460440200241384f0d030c0405200028020020016a41ca7e6a2d00002002410874722102200141016a21010c010b000b000b200141f7014d0440200341c07e6a0f0b024020002802042201200341897e6a22024d047f100020002802040520010b4102490d0020002802002d00010d0010000b200241054f044010000b20002802002d000145044010000b4100210241f701210103402001200346044020024138490d0305200028020020016a418a7e6a2d00002002410874722102200141016a21010c010b0b0b200241ff7d490d010b10000b20020b5c00024020002d0000410171450440200041003b01000c010b200028020841003a00002000410036020420002d0000410171450d00200041003602000b20002001290200370200200041086a200141086a280200360200200110b3010b3902017f017e230041106b220124002001200010b90120012903002102200141106a2400420020024201837d200242018885a74118744118750b6202027f017e230041206b22012400200141186a4100360200200141106a4200370300200141086a42003703002001420037030020012000ad42388622034238872003423f8710ba01210020012802002102200041046a1015200141206a240020020b2701017f230041106b220224002000410010132002200110121014410110131a200241106a24000ba10102027f027e230041106b22022400200110aa0102400240200110ab01450d002001280204450d0020012802002d000041c001490d010b10000b200241086a200110ac01200228020c220141114f044010000b20022802082103034020010440200542088620044238888421052001417f6a210120033100002004420886842104200341016a21030c010b0b2000200437030020002005370308200241106a24000b2301017e20002002423f87220320014201868520024201862001423f888420038510560b2301017e20002002423f87220320014201868520024201862001423f888420038510590b1301017e20002001ac22022002423f8710ba010b4c01017f2000410036020c200041106a2003360200200104402001104d21040b200020043602002000200420024101746a22023602082000200420014101746a36020c2000200236020420000b870101037f200120012802042000280204200028020022046b22036b2202360204200341004a044020022004200310361a200128020421020b200028020021032000200236020020012003360204200028020421022000200128020836020420012002360208200028020821022000200128020c3602082001200236020c200120012802043602000b2b01027f200028020821012000280204210203402001200247044020002001417e6a22013602080c010b0b0b0b0020002001410110c6010b0b0020002001410010c6010b170020002001280204200141086a280200411c10a9011a0bb70102057f017e230041106b22032400200041046a210102402000280200220204402001280200220504402005200041086a2802006a21040b20002004360204200041086a2002360200200341086a200141002004200210cb0110cc0120002003290308220637020420004100200028020022012006422088a76b2202200220014b1b3602000c010b200020012802002201047f2001200041086a2802006a0541000b360204200041086a41003602000b200341106a24000b3901017f027f200041186a28020022010440200041086a280200200041146a280200200110550c010b20000b2201200128020041016a3602000b220002402000280204044020002802002d000041bf014b0d010b10000b200010b2010be70101037f230041106b2204240020004200370200200041086a410036020020012802042103024002402002450440200321020c010b410021022003450d002003210220012802002d000041c001490d00200441086a200110cd0120004100200428020c220120042802082202200110cb0122032003417f461b20024520012003497222031b220536020820004100200220031b3602042000200120056b3602000c010b20012802002103200128020421012000410036020020004100200220016b20034520022001497222021b36020820004100200120036a20021b3602040b200441106a24000b3501017f230041106b220041908c0436020c41800c200028020c41076a417871220036020041840c200036020041880c3f003602000b10002002044020002001200210361a0b0b3001017f200028020445044041000f0b4101210120002802002c0000417f4c047f200010ca01200010b4016a0520010b0b5b00027f027f41002000280204450d001a410020002802002c0000417f4a0d011a20002802002d0000220041bf014d04404100200041b801490d011a200041c97e6a0c010b4100200041f801490d001a200041897e6a0b41016a0b0b2901017f230041206b22022400200241086a20002001411410a90110c9012100200241206a240020000b5b01027f2000027f0240200128020022054504400c010b200220036a200128020422014b0d0020012002490d00410020012003490d011a200220056a2104200120026b20032003417f461b0c010b41000b360204200020043602000b2401017f200110b401220220012802044b044010000b20002001200110ca01200210cc010b2f002000200210cf01200028020020002802046a2001200210361a2000200028020420026a3602042000200310d0010b1b00200028020420016a220120002802084b04402000200110570b0b830201047f02402001450d00034020002802102202200028020c460d01200241786a28020020014904401000200028021021020b200241786a2203200328020020016b220136020020010d012000200336021020004101200028020422032002417c6a28020022016b22021054220441016a20024138491b220520036a10d101200120002802006a220320056a2003200210490240200241374d0440200028020020016a200241406a3a00000c010b200441f7016a220341ff014d0440200028020020016a20033a00002000280200200120046a6a210103402002450d02200120023a0000200241087621022001417f6a21010c000b000b10000b410121010c000b000b0b0f00200020011057200020013602040b26002000410110cf01200028020020002802046a20013a00002000200028020441016a3602040b6001027f20011054220241b7016a22034180024e044010000b2000200341ff017110d2012000200028020420026a10d101200028020420002802006a417f6a2100034020010440200020013a0000200141087621012000417f6a21000c010b0b0b0bfa0301004180080bf203746f70696331006461746131006a735f636f6e7472616374006576656e740073657455696e7433324576740073657455696e743136457674007472616e7366657200696e69740073657455696e74380067657455696e74380073657455696e7431360067657455696e7431360073657455696e7433320067657455696e7433320073657455696e7436340067657455696e74363400736574537472696e6700676574537472696e6700736574426f6f6c00676574426f6f6c00736574436861720067657443686172007365744d657373616765006765744d657373616765007365744d794d657373616765006765744d794d65737361676500736574496e743800676574496e743800736574496e74313600676574496e74313600736574496e74333200676574496e74333200736574496e74363400676574496e74363400736574566563746f7200676574566563746f72007365744d6170006765744d617000746573744d756c7469506172616d730073657442797465730067657442797465730073657441727261790067657441727261790073657450616972006765745061697200736574536574006765745365740073657446697865644861736800676574466978656448617368007365744c697374006765744c697374007365744164647265737300676574416464726573738ac988e9b5e87ed4669d83" +# testinput=['d7','85', '68', '65', '6c', '6c', '6f', '88', '74', '68', '69', '73', '20', '77', '61', '79', '87', '67', '6f', '20', '68', '6f', '6d', '65'] +# mapdata=['f8', '47', 'e3', '8b', '68', '65', '6c', '6c', '6f', '20', '77', '6f', '72', '6c', '64', '96', '6d', '61', '79', '20', '74', '68', '65', '20', '66', '6f', '72', '63', '65', '20', '77', '69', '74', '68', '20', '79', '6f', '75', 'e2', '8b', '68', '6f', '77', '20', '61', '72', '65', '20', '79', '6f', '75', '95', '66', '69', '6e', '65', '2c', '74', '68', '61', '6e', '6b', '73', '20', '61', '6e', '64', '20', '79', '6f', '75', '20', '3f'] +h1=['cb', '8a', '48', '65', '6c', '6c', '6f', '57', '6f', '72', '6c', '64'] +data1=['d6', 'cb', '8a', '48', '65', '6c', '6c', '6f', '57', '6f', '72', '6c', '64', '84', '57', '61', '73', '6d', '84', '47', '6f', '6f', '64'] +aa = rlp_decode(data1) +print(aa) +#rlp_decode之后的数据格式 +# paramABI=((['68', '65', '6c', '6c', '6f', '20', '77', '6f', '72', '6c', '64'], ['6d', '61', '79', '20', '74', '68', '65', '20', '66', '6f', '72', '63', '65', '20', '77', '69', '74', '68', '20', '79', '6f', '75']), (['68', '6f', '77', '20', '61', '72', '65', '20', '79', '6f', '75'], ['66', '69', '6e', '65', '2c', '74', '68', '61', '6e', '6b', '73', '20', '61', '6e', '64', '20', '79', '6f', '75', '20', '3f'])) +# paramabi=(['9a', '6e', 'bb', 'c6', 'a5', '9a', 'b5', 'be'], (([['48', '65', '6c', '6c', '6f', '57', '6f', '72', '6c', '64']], ['57', '61', '73', '6d'], ['47', '6f', '6f', '64']),)) + +# aa=rlp_encode(paramabi) +# print(aa) \ No newline at end of file diff --git a/tests/WasmContract1.py b/tests/WasmContract1.py new file mode 100644 index 0000000..4a6e396 --- /dev/null +++ b/tests/WasmContract1.py @@ -0,0 +1,223 @@ +from client_sdk_python import Web3, HTTPProvider +from client_sdk_python.eth import PlatON +# import binascii +# f = open('D:/juzhen/JS_wasmtest1.wasm','rb') +# contents=f.read() +# bytecode=binascii.b2a_hex(contents) + +true = True +false = False + +w3 = Web3(HTTPProvider("http://10.1.1.2:6789")) +platon = PlatON(w3) +print(w3.isConnected()) +# from_address = "lax1du4w3q0h5gpxh2vpdvtl7m8h2p9qj40a2krhx7" +from_address = "lax1uqug0zq7rcxddndleq4ux2ft3tv6dqljphydrl" +print(from_address) + +# send_privatekey = "de66562d36f1db46a55f966cfb0eb0981e3e219aa6050612e9f3cb29b8b5c89d" +send_privatekey = "983759fe9aac227c535b21d78792d79c2f399b1d43db46ae6d50a33875301557" +bytecode='0061736d01000000015c1060027f7f0060017f017f60027f7f017f60017f0060037f7f7f017f60037f7f7f0060047f7f7f7f0060000060047f7f7f7f017f60027f7e0060017f017e60037f7e7e0060037f7e7e017f60017e017f60057f7f7f7f7f006000017f02ce010903656e760c706c61746f6e5f70616e6963000703656e760b706c61746f6e5f73686133000603656e7617706c61746f6e5f6765745f696e7075745f6c656e677468000f03656e7610706c61746f6e5f6765745f696e707574000303656e7617706c61746f6e5f6765745f73746174655f6c656e677468000203656e7610706c61746f6e5f6765745f7374617465000803656e7610706c61746f6e5f7365745f7374617465000603656e760c706c61746f6e5f6576656e74000603656e760d706c61746f6e5f72657475726e000003cd01cb010700020200040000010202020302020500000e000000020001000200010002000001020600020002000200000204000002010102040506000303010400050402050500000104020503010001040c00040b01000004080304000107070704050a0a030103010101010101010d09010000000003000100020100010001010001010a0d09000100000100000201000100010001000001000100010003010001000108030100020100090001030100010100000c0b0208000300000003030105070501010206000600000000000405017001050505030100020608017f0141908c040b073904066d656d6f72790200115f5f7761736d5f63616c6c5f63746f727300090f5f5f66756e63735f6f6e5f65786974006506696e766f6b650063090a010041010b04202124250af0b902cb01050010c7010baa0301097f230041c0016b22022400200241b908100b2104200241e8006a4102100c2103200241d8006a2004100d200241c8006a2000100d200241406b4100360200200241386a4200370300200241306a420037030020024200370328200241286a20022802582204200228025c100e20022802482205200228024c100e210620032002280228100f2003200241d8006a10102003200241c8006a1010200328020c200341106a28020047044010000b2003280204210720032802002108200241106a1011210020024180016a200110122101200241a8016a4100360200200241a0016a420037030020024198016a4200370300200242003703900120024190016a41001013200241b0016a200110121014410110132109200228029001210a200941046a10152000200a100f20004101101620024190016a200110121017220028020c200041106a28020047044010000b20082007200028020020002802041007200028020c22010440200020013602100b200641046a1015200504402002200536024c0b200404402002200436025c0b200328020c22000440200320003602100b200241c0016a24000b910101027f20004200370200200041086a410036020020012102024003402002410371044020022d0000450d02200241016a21020c010b0b2002417c6a21020340200241046a22022802002203417f73200341fffdfb776a7141808182847871450d000b0340200341ff0171450d01200241016a2d00002103200241016a21020c000b000b20002001200220016b105020000b1d0020001051200041146a41003602002000420037020c2000200110160b8b0101037f230041306b22032400200341186a1011220220011052100f2002200341086a200110121017220128020c200141106a28020047044010000b200041003602082000420037020020012802042102200128020021042000412010532004200220002802002202200028020420026b1001200128020c22000440200120003602100b200341306a24000b8b0101017f024020012002460440410121030c010b4101210302400240200220016b2202410146044020012c0000417f4c0d010c030b200241374b0d010b200241016a21030c010b2002105420026a41016a21030b027f200041186a28020022010440200041086a280200200041146a280200200110550c010b20000b2201200128020020036a36020020000b1300200028020820014904402000200110570b0b1600200020012802002200200128020420006b10581a0b190020001051200041146a41003602002000420037020c20000b4d01017f20004200370200200041086a2202410036020020012d0000410171450440200020012902003702002002200141086a28020036020020000f0b200020012802082001280204105020000bc30c02077f027e230041306b22042400200041046a2107027f20014101460440200041086a280200200041146a280200200041186a220228020022031055280200210120022003417f6a3602002007105a4180104f044020072000410c6a280200417c6a105b0b200141384f047f2001105420016a0520010b41016a2102200041186a28020022010440200041086a280200200041146a280200200110550c020b20000c010b02402007105a0d00200041146a28020022014180084f0440200020014180786a360214200041086a2201280200220228020021032001200241046a360200200420033602182007200441186a105c0c010b2000410c6a2802002202200041086a2802006b4102752203200041106a2205280200220620002802046b2201410275490440418020103a2105200220064704400240200028020c220120002802102202470d0020002802082203200028020422064b04402000200320012003200320066b41027541016a417e6d41027422026a105d220136020c2000200028020820026a3602080c010b200441186a200220066b2201410175410120011b22012001410276200041106a105e2102200028020c210320002802082101034020012003470440200228020820012802003602002002200228020841046a360208200141046a21010c010b0b200029020421092000200229020037020420022009370200200029020c21092000200229020837020c200220093702082002105f200028020c21010b200120053602002000200028020c41046a36020c0c020b02402000280208220120002802042202470d00200028020c2203200028021022064904402000200120032003200620036b41027541016a41026d41027422026a106022013602082000200028020c20026a36020c0c010b200441186a200620026b2201410175410120011b2201200141036a410276200041106a105e2102200028020c210320002802082101034020012003470440200228020820012802003602002002200228020841046a360208200141046a21010c010b0b200029020421092000200229020037020420022009370200200029020c21092000200229020837020c200220093702082002105f200028020821010b2001417c6a2005360200200020002802082201417c6a22023602082002280200210220002001360208200420023602182007200441186a105c0c010b20042001410175410120011b20032005105e2102418020103a2106024020022802082201200228020c2203470d0020022802042205200228020022084b04402002200520012005200520086b41027541016a417e6d41027422036a105d22013602082002200228020420036a3602040c010b200441186a200320086b2201410175410120011b22012001410276200241106a280200105e21032002280208210520022802042101034020012005470440200328020820012802003602002003200328020841046a360208200141046a21010c010b0b2002290200210920022003290200370200200320093702002002290208210920022003290208370208200320093702082003105f200228020821010b200120063602002002200228020841046a360208200028020c2105034020002802082005460440200028020421012000200228020036020420022001360200200228020421012002200536020420002001360208200029020c21092000200229020837020c200220093702082002105f052005417c6a210502402002280204220120022802002203470d0020022802082206200228020c22084904402002200120062006200820066b41027541016a41026d41027422036a106022013602042002200228020820036a3602080c010b200441186a200820036b2201410175410120011b2201200141036a4102762002280210105e21062002280208210320022802042101034020012003470440200428022020012802003602002004200428022041046a360220200141046a21010c010b0b20022902002109200220042903183702002002290208210a20022004290320370208200420093703182004200a3703202006105f200228020421010b2001417c6a200528020036020020022002280204417c6a3602040c010b0b0b200441186a20071061200428021c410036020041012102200041186a0b2201200128020020026a360200200441306a240020000ba10101037f41012103024002400240200128020420012d00002202410176200241017122041b220241014d0440200241016b0d032001280208200141016a20041b2c0000417f4c0d010c030b200241374b0d010b200241016a21030c010b2002105420026a41016a21030b027f200041186a28020022010440200041086a280200200041146a280200200110550c010b20000b2201200128020020036a36020020000bea0101047f230041106b22042400200028020422012000280210220241087641fcffff07716a2103027f410020012000280208460d001a2003280200200241ff07714102746a0b2101200441086a20001061200428020c210203400240200120024604402000410036021420002802082103200028020421010340200320016b41027522024103490d022000200141046a22013602040c000b000b200141046a220120032802006b418020470d0120032802042101200341046a21030c010b0b2002417f6a220241014d04402000418004418008200241016b1b3602100b20002001105b200441106a24000b8e0201057f2001044020002802042105200041106a2802002202200041146a280200220349044020022001ad2005ad422086843702002000200028021041086a36021020000f0b027f41002002200028020c22046b410375220641016a2202200320046b2203410275220420042002491b41ffffffff01200341037541ffffffff00491b2204450d001a2004410374103a0b2102200220064103746a22032001ad2005ad4220868437020020032000280210200028020c22066b22016b2105200220044103746a2102200341086a2103200141014e044020052006200110361a0b20002002360214200020033602102000200536020c20000f0b200041c00110d201200041004100410110ce0120000b2c01017f20002001280208200141016a20012d0000220041017122021b2001280204200041017620021b10580bc80301087f230041c0016b22032400200341ac08100b2105200341e8006a4102100c2104200341d8006a2005100d200341c8006a2000100d200341406b4100360200200341386a4200370300200341306a420037030020034200370328200341286a20032802582205200328025c100e20032802482206200328024c100e210720042003280228100f2004200341d8006a10102004200341c8006a1010200428020c200441106a28020047044010000b2004280204210820042802002109200341106a1011210020034180016a200110122101200320023b018c01200341a8016a4100360200200341a0016a420037030020034198016a4200370300200342003703900120034190016a41001013200341b0016a200110121014220220032f018c0110192002410110132102200328029001210a200241046a10152000200a100f20004102101620034190016a200110121017220020032f018c01101a200028020c200041106a28020047044010000b20092008200028020020002802041007200028020c22010440200020013602100b200741046a1015200604402003200636024c0b200504402003200536025c0b200428020c22000440200420003602100b200341c0016a24000b0c0020002001ad420010561a0b0b0020002001ad420010590bf20301067f230041d0016b22052400200541086a419f08100b2107200541f0006a4103100c2106200541e0006a2007100d200541d0006a2000100d200541c8006a4100360200200541406b4200370300200541386a420037030020054200370330200541306a200528026022002005280264100e200528025022072005280254100e22082001101920062005280230100f2006200541e0006a10102006200541d0006a101020062001101a200628020c200641106a28020047044010000b200628020421092006280200210a200541186a1011210120054188016a20021012210220052004360298012005200336029401200541b8016a4100360200200541b0016a4200370300200541a8016a4200370300200542003703a001200541a0016a41001013200541c0016a2002101210142203200528029401101920032005280298011019200341011013210320052802a0012104200341046a101520012004100f200141031016200541a0016a2002101210172201200528029401101a2001200528029801101a200128020c200141106a28020047044010000b200a2009200128020020012802041007200128020c22020440200120023602100b200841046a101520070440200520073602540b20000440200520003602640b200628020c22010440200620013602100b200541d0016a24000b2e01017f230041206b22022400200241106a418d08100b2002419908100b100a200020013a0010200241206a24000b3301017f230041206b22022400200241106a418008100b2002418708100b20011018200041286a20013b0100200241206a24000b3701017f230041206b22022400200241106a418008100b20012002418708100b20012001101b200041406b2001360200200241206a24000b930201047f20002001470440200128020420012d00002202410176200241017122041b2102200141016a210320012802082105410a21012005200320041b210420002d0000410171220304402000280200417e71417f6a21010b200220014d0440027f2003044020002802080c010b200041016a0b21012002044020012004200210490b200120026a41003a000020002d000041017104402000200236020420000f0b200020024101743a000020000f0b416f2103200141e6ffffff074d0440410b20014101742201200220022001491b220141106a4170712001410b491b21030b2003103a22012004200210c801200020023602042000200341017236020020002001360208200120026a41003a00000b20000b0d00200041b0016a20013a00000b0b00200041b0016a2c00000b230020002001101f1a2000410c6a2001410c6a101f1a200041186a200141186a101f1a0b25002000200110121a2000410c6a2001410c6a10121a200041186a200141186a10121a20000b0d00200041c8026a20013a00000b0b00200041c8026a2c00000b9e0101047f2000200147044020012802042203200128020022026b41017522042000280208200028020022016b4101754d0440200041046a21052004200028020420016b41017522004b04402002200220004101746a22002001104e1a20002003200510460f0b2005200220032001104e3602000f0b2001044020004100360208200042003702000b200020002004104f104c20022003200041046a10460b0b3e01017f2000420037020020004100360208200128020420012802006b2202044020002002410175104c20012802002001280204200041046a10460b20000b3001027f200141046a21032001280200210203402002200346044020004188046a20011029052002102a21020c010b0b0be00201067f230041206b22042400024020002001460d00200141046a21062001280200210102402000280208450d00200028020021032000200041046a3602002000410036020820002802042102200041003602042002410036020820032802042202200320021b2102034020022203450d0120012006470440200341106a200141106a101f21072003411c6a2001411c6a101f1a024020032802082202450440410021020c010b2003200228020022054604402002410036020020022802042205450d012005104321020c010b200241003602042005450d002005104321020b2000200441106a2007104421072000200428021020072003103f2001102a21010c010b0b0340200328020822030d000b200621010b034020012006460d01200441106a2000200141106a104a20002004410c6a2004280210220341106a104421022000200428020c20022003103f2001102a21010c000b000b200441206a24000b3601017f024020002802042201044003402001220028020022010d000c020b000b0340200020002802082200280200470d000b0b20000bd60101067f230041106b22022400200042003702042000200041046a2203360200200141046a21062001280200210103402001200646450440200141106a21050240027f027f0240024020032000280200460440200321040c010b2003103b220441106a2005103c450d010b20032802004504402002200336020c2003210420030c030b2002200436020c200441046a0c010b20002002410c6a2005103d0b22042802000d01200228020c0b2107200220002005104a2000200720042002280200103f0b2001102a21010c010b0b200241106a240020000b2300200041d0016a2001101f1a20004198016a20033a0000200041f8026a20023602000b920101047f2000200147044020012802042203200128020022026b22042000280208200028020022016b4d0440200041046a21052004200028020420016b22004b04402002200020026a2200200110471a20002003200510460f0b200520022003200110473602000f0b2001044020004100360208200042003702000b2000200020041048104520022003200041046a10460b0b3b01017f2000420037020020004100360208200128020420012802006b2202044020002002104520012802002001280204200041046a10460b20000b2601017f0340200241f800470440200020026a200120026a101f1a2002410c6a21020c010b0b0b2301017f0340200020026a200120026a10121a2002410c6a220241f800470d000b20000b130020002001101f1a2000200128020c36020c0b15002000200110121a2000200128020c36020c20000b3001027f200141046a210320012802002102034020022003460440200041f8066a20011034052002102a21020c010b0b0bd30201067f230041206b22042400024020002001460d00200141046a21062001280200210102402000280208450d00200028020021032000200041046a3602002000410036020820002802042102200041003602042002410036020820032802042202200320021b2102034020022203450d0120012006470440200341106a200141106a101f2107024020032802082202450440410021020c010b2003200228020022054604402002410036020020022802042205450d012005104321020c010b200241003602042005450d002005104321020b2000200441106a2007104421072000200428021020072003103f2001102a21010c010b0b0340200328020822030d000b200621010b034020012006460d01200441106a2000200141106a103e20002004410c6a2004280210220341106a104421022000200428020c20022003103f2001102a21010c000b000b200441206a24000bd60101067f230041106b22022400200042003702042000200041046a2203360200200141046a21062001280200210103402001200646450440200141106a21050240027f027f0240024020032000280200460440200321040c010b2003103b220441106a2005103c450d010b20032802004504402002200336020c2003210420030c030b2002200436020c200441046a0c010b20002002410c6a2005103d0b22042802000d01200228020c0b2107200220002005103e2000200720042002280200103f0b2001102a21010c010b0b200241106a240020000bfc0801067f03400240200020046a2105200120046a210320022004460d002003410371450d00200520032d00003a0000200441016a21040c010b0b200220046b210602402005410371220745044003402006411049450440200020046a2203200120046a2205290200370200200341086a200541086a290200370200200441106a2104200641706a21060c010b0b027f2006410871450440200120046a2103200020046a0c010b200020046a2205200120046a2204290200370200200441086a2103200541086a0b21042006410471044020042003280200360200200341046a2103200441046a21040b20064102710440200420032f00003b0000200341026a2103200441026a21040b2006410171450d01200420032d00003a000020000f0b024020064120490d002007417f6a220741024b0d00024002400240024002400240200741016b0e020102000b2005200120046a220328020022073a0000200541016a200341016a2f00003b0000200041036a2108200220046b417d6a2106034020064111490d03200420086a2203200120046a220541046a2802002202410874200741187672360200200341046a200541086a2802002207410874200241187672360200200341086a2005410c6a28020022024108742007411876723602002003410c6a200541106a2802002207410874200241187672360200200441106a2104200641706a21060c000b000b2005200120046a220328020022073a0000200541016a200341016a2d00003a0000200041026a2108200220046b417e6a2106034020064112490d03200420086a2203200120046a220541046a2802002202411074200741107672360200200341046a200541086a2802002207411074200241107672360200200341086a2005410c6a28020022024110742007411076723602002003410c6a200541106a2802002207411074200241107672360200200441106a2104200641706a21060c000b000b2005200120046a28020022073a0000200041016a21082004417f7320026a2106034020064113490d03200420086a2203200120046a220541046a2802002202411874200741087672360200200341046a200541086a2802002207411874200241087672360200200341086a2005410c6a28020022024118742007410876723602002003410c6a200541106a2802002207411874200241087672360200200441106a2104200641706a21060c000b000b200120046a41036a2103200020046a41036a21050c020b200120046a41026a2103200020046a41026a21050c010b200120046a41016a2103200020046a41016a21050b20064110710440200520032d00003a00002005200328000136000120052003290005370005200520032f000d3b000d200520032d000f3a000f200541106a2105200341106a21030b2006410871044020052003290000370000200541086a2105200341086a21030b2006410471044020052003280000360000200541046a2105200341046a21030b20064102710440200520032f00003b0000200541026a2105200341026a21030b2006410171450d00200520032d00003a00000b20000b2b01027f200141046a210203402002280200220341046a210220012003470d000b200041a80b6a200110380bbe0201057f024020002001460d00200041046a2102200141046a21030340200228020021020240027f4101200328020022032001460d001a20002002470d0141000b210402402000200246044020040d044114103a22054100360200200541086a200341086a10121a20052104410121060340200120032802042203460d024114103a220241086a200341086a10121a2002200436020020042002360204200641016a2106200221040c000b000b200228020022032000280200220128020436020420012802042003360200034020002002460d0420002000280208417f6a360208200228020421020c000b000b2000280200220220053602042005200236020020002004360200200420003602042000200028020820066a3602080c020b200241086a200341086a101f1a200241046a2102200341046a21030c000b000b0b840101037f200041003602082000200036020420002000360200200141046a2102037f20022802002203200146047f2000054114103a22024100360200200241086a200341086a10121a20022000360204200028020021042000200236020020022004360200200420023602042000200028020841016a360208200341046a21020c010b0b0b0b002000410120001b10620b3e01027f024020002802002201044003402001220228020422010d000c020b000b03402000280208220228020020004621012002210020010d000b0b20020bb20101067f02400240200128020420012d00002202410176200241017122031b2205200028020420002d00002202410176200241017122041b2206200520064922071b2202450d002000280208200041016a20041b21002001280208200141016a20031b210103402002450d0120002d0000220320012d00002204460440200141016a2101200041016a21002002417f6a21020c010b0b200320046b22020d010b417f200720062005491b21020b2002411f760b890101027f200041046a2103024020002802042200044002400340024002402002200041106a2204103c0440200028020022040d012001200036020020000f0b20042002103c450d03200041046a210320002802042204450d01200321000b20002103200421000c010b0b2001200036020020030f0b200120003602000c010b200120033602000b20030b2d01017f2000411c103a22033602002000200141046a360204200341106a200210121a200041086a41013a00000b480020032001360208200342003702002002200336020020002802002802002201044020002001360200200228020021030b2000280204200310402000200028020841016a3602080bec0101037f200120002001463a000c03400240024020002001460d00200128020822022d000c0d002002200228020822032802002204460440024020032802042204450d0020042d000c0d002004410c6a21010c030b20012002280200470440200210412002280208220228020821030b200241013a000c200341003a000c200310420f0b02402004450d0020042d000c0d002004410c6a21010c020b20012002280200460440200210422002280208220228020821030b200241013a000c200341003a000c200310410b0f0b200241013a000c200320002003463a000c200141013a0000200321010c000b000b5101027f200020002802042201280200220236020420020440200220003602080b200120002802083602082000280208220220022802002000474102746a200136020020002001360208200120003602000b5101027f200020002802002201280204220236020020020440200220003602080b200120002802083602082000280208220220022802002000474102746a200136020020002001360208200120003602040b1d01017f03402000220128020022000d00200128020422000d000b20010b5c01017f0240200028020422030440034002402002200341106a103c044020032802002200450d040c010b200328020422000d0020012003360200200341046a0f0b200021030c000b000b200041046a21030b2001200336020020030b2001017f20002001103a2202360200200020023602042000200120026a3602080b2800200120006b220141014e044020022802002000200110361a2002200228020020016a3602000b0b1900200120006b2201044020022000200110490b200120026a0b2e01017f2001200028020820002802006b2200410174220220022001491b41ffffffff07200041ffffffff03491b0b8d0301037f024020002001460d00200120006b20026b410020024101746b4d044020002001200210361a0c010b20002001734103712103027f024020002001490440200020030d021a410021030340200120036a2105200020036a2204410371450440200220036b210241002103034020024104490d04200320046a200320056a280200360200200341046a21032002417c6a21020c000b000b20022003460d04200420052d00003a0000200341016a21030c000b000b024020030d002001417f6a21040340200020026a22034103714504402001417c6a21032000417c6a2104034020024104490d03200220046a200220036a2802003602002002417c6a21020c000b000b2002450d042003417f6a200220046a2d00003a00002002417f6a21020c000b000b2001417f6a210103402002450d03200020026a417f6a200120026a2d00003a00002002417f6a21020c000b000b200320056a2101200320046a0b210303402002450d01200320012d00003a00002002417f6a2102200341016a2103200141016a21010c000b000b0b2c01017f20004128103a22033602002000200141046a360204200341106a2002104b200041086a41013a00000b16002000200110121a2000410c6a2001410c6a10121a0b2301017f20002001104d2202360200200020023602042000200220014101746a3602080b09002000410174103a0b2501017f200120006b220141017521032001044020022000200110490b200220034101746a0b2a002001200028020820002802006b220020002001491b41ffffffff07200041017541ffffffff03491b0b5b01027f02402002410a4d0440200020024101743a0000200041016a21030c010b200241106a4170712204103a21032000200236020420002004410172360200200020033602080b20032001200210c801200220036a41003a00000b160020004100360208200042003702002000410010570b5801027f230041306b22012400200141286a4100360200200141206a4200370300200141186a420037030020014200370310200141106a2001200010121014210020012802102102200041046a1015200141306a240020020bdd0101047f024020002802042203200028020022026b22042001490440200028020820036b200120046b22024f04400340200341003a00002000200028020441016a22033602042002417f6a22020d000c030b000b200020011048220104402001103a21050b200420056a220421030340200341003a0000200341016a21032002417f6a22020d000b200120056a210520042000280204200028020022046b22016b2102200141014e044020022004200110361a0b2000200536020820002003360204200020023602000f0b200420014d0d002000200120026a3602040b0b1e01017f03402000044020004108762100200141016a21010c010b0b20010b25002000200120026a417f6a220241087641fcffff07716a280200200241ff07714102746a0b900101027f4101210420014280015441002002501b450440034020012002845045044020024238862001420888842101200341016a2103200242088821020c010b0b200341384f047f2003105420036a0520030b41016a21040b027f200041186a28020022030440200041086a280200200041146a280200200310550c010b20000b2203200328020020046a36020020000b2f01017f2000280208200149044020011062200028020020002802041036210220002001360208200020023602000b0b7001017f4101210302400240024002402002410146044020012c000022024100480d012000200241ff017110d2010c040b200241374b0d01200221030b200020034180017341ff017110d2010c010b2000200210d301200221030b200020012003410010ce010b2000410110d00120000bcf0202037f027e02402001200284500440200041800110d2010c010b20014280015441002002501b4504402001210720022106034020062007845045044020064238862007420888842107200341016a2103200642088821060c010b0b0240200341384f04402003210403402004044020044108762104200541016a21050c010b0b200541c9004f044010000b2000200541b77f6a41ff017110d2012000200028020420056a10d101200028020420002802006a417f6a21052003210403402004450d02200520043a0000200441087621042005417f6a21050c000b000b200020034180017341ff017110d2010b2000200028020420036a10d101200028020420002802006a417f6a210303402001200284500d02200320013c0000200242388620014208888421012003417f6a2103200242088821020c000b000b20002001a741ff017110d2010b2000410110d0010b2801017f200028020820002802046b2201410874417f6a410020011b200028021420002802106a6b0b2501017f200028020821020340200120024645044020002002417c6a22023602080c010b0b0ba10202057f017e230041206b22052400024020002802082202200028020c2203470d0020002802042204200028020022064b04402000200420022004200420066b41027541016a417e6d41027422036a105d22023602082000200028020420036a3602040c010b200541086a200320066b2202410175410120021b220220024102762000410c6a105e2103200028020821042000280204210203402002200446450440200328020820022802003602002003200328020841046a360208200241046a21020c010b0b2000290200210720002003290200370200200320073702002000290208210720002003290208370208200320073702082003105f200028020821020b200220012802003602002000200028020841046a360208200541206a24000b2501017f200120006b220141027521032001044020022000200110490b200220034102746a0b4f01017f2000410036020c200041106a2003360200200104402001410274103a21040b200020043602002000200420024102746a22023602082000200420014102746a36020c2000200236020420000b2b01027f200028020821012000280204210203402001200247044020002001417c6a22013602080c010b0b0b1b00200120006b22010440200220016b22022000200110490b20020b4f01037f20012802042203200128021020012802146a220441087641fcffff07716a21022000027f410020032001280208460d001a2002280200200441ff07714102746a0b360204200020023602000b9b0101047f230041106b220124002001200036020c2000047f41880c200041086a2202411076220041880c2802006a220336020041840c41840c280200220420026a41076a417871220236020002400240200341107420024d044041880c200341016a360200200041016a21000c010b2000450d010b200040000d0010000b20042001410c6a4104103641086a0541000b2100200141106a240020000b090010c701106410650bc52602057f027e230041c0166b2201240010022200106222021003200141d00a6a200141086a20022000106622004100106702400240200141d00a6a10682205500d0041c208106920055104402000106a200141d00a6a106b106c0c020b41c708106920055104402000106d410247044010000b200141d00a6a200041011067200141d00a6a106e2100200141d00a6a106b22022000101c2002106c0c020b41d008106920055104402000106a200141d00a6a106b22032d00102102200141b8086a101122002002106f100f20002002101a200028020c200041106a28020047044010000b200028020020002802041008200028020c22020440200020023602100b2003106c0c020b41d908106920055104402000106d410247044010000b200141d00a6a200041011067200141d00a6a10702100200141d00a6a106b22022000101d2002106c0c020b41e308106920055104402000106a200141d00a6a106b220341286a2f01002102200141b8086a1011220020021071100f20002002101a200028020c200041106a28020047044010000b200028020020002802041008200028020c22020440200020023602100b2003106c0c020b41ed08106920055104402000106d410247044010000b200141d00a6a200041011067200141d00a6a10722100200141d00a6a106b22022000101e2002106c0c020b41f708106920055104402000106a200141d00a6a106b220341406b2802002102200141b8086a1011220020021073100f20002002101a200028020c200041106a28020047044010000b200028020020002802041008200028020c22020440200020023602100b2003106c0c020b418109106920055104402000106d410247044010000b200141d00a6a200041011067200141d00a6a10682105200141d00a6a106b220041d8006a20053703002000106c0c020b418b09106920055104402000106a200141d00a6a106b220241d8006a2903002105200141b8086a1011220020051074100f200020051075200028020c200041106a28020047044010000b200028020020002802041008200028020c22030440200020033602100b2002106c0c020b41950910692005510440200141b8066a107621022000106d410247044010000b200141d00a6a200041011067200141d00a6a20021077200141d00a6a106b220041f8006a200141b8086a20021012101f1a2000106c0c020b419f09106920055104402000106a200141a0046a200141d00a6a106b220241f8006a10122100200141b8086a1011220320001052100f2003200141b8066a200010121017220028020c200041106a28020047044010000b200028020020002802041008200028020c22030440200020033602100b2002106c0c020b41a90910692005510440200141003a00b8082000106d410247044010000b200141d00a6a200041011067200141d00a6a200141b8086a1078200141d00a6a106b22004198016a20012d00b8083a00002000106c0c020b41b109106920055104402000106a200141d00a6a106b22034198016a2d00002102200141b8086a101122002002106f100f20002002101a200028020c200041106a28020047044010000b200028020020002802041008200028020c22020440200020023602100b2003106c0c020b41b909106920055104402000410110790c020b41c1091069200551044020004102107a0c020b41c90910692005510440200141b8066a107b2000106d410247044010000b200141d00a6a200041011067200141d00a6a200141b8066a107c200141d00a6a106b220041d0016a200141b8086a200141b8066a1012101f1a2000106c0c020b41d409106920055104402000106a200141b8066a200141d00a6a106b220241d0016a10121a200141b8086a10112200200141b8066a107d100f2000200141b8066a107e200028020c200041106a28020047044010000b200028020020002802041008200028020c22030440200020033602100b2002106c0c020b41df0910692005510440200141b8066a4124107f1a200141b8066a10800121022000106d410247044010000b200141d00a6a200041011067200141d00a6a2002108101200141d00a6a106b22004190026a200141b8086a2002102310222000106c0c020b41ec09106920055104402000106a200141b8086a200141d00a6a106b22034190026a10232102200141b8066a101122002002108201100f20002002108301200028020c200041106a28020047044010000b200028020020002802041008200028020c22020440200020023602100b2003106c0c020b41f909106920055104402000410310790c020b41810a1069200551044020004104107a0c020b41890a106920055104402000106d410247044010000b200141d00a6a200041011067200141d00a6a1084012100200141d00a6a106b220241e0026a20003b01002002106c0c020b41920a106920055104402000106a200141d00a6a106b220341e0026a2e01002102200141b8086a101122002002108501100f20002002108601200028020c200041106a28020047044010000b200028020020002802041008200028020c22020440200020023602100b2003106c0c020b419b0a106920055104402000106d410247044010000b200141d00a6a200041011067200141d00a6a1087012100200141d00a6a106b220241f8026a20003602002002106c0c020b41a40a106920055104402000106a200141d00a6a106b220341f8026a2802002102200141b8086a101122002002108801100f20002002108601200028020c200041106a28020047044010000b200028020020002802041008200028020c22020440200020023602100b2003106c0c020b41ad0a106920055104402000106d410247044010000b200141d00a6a200041011067200141d00a6a1089012105200141d00a6a106b22004190036a20053703002000106c0c020b41b60a106920055104402000106a200141d00a6a106b22024190036a2903002105200141b8086a101122002005108a01100f20002005108b01200028020c200041106a28020047044010000b200028020020002802041008200028020c22030440200020033602100b2002106c0c020b41bf0a10692005510440200141003602c006200142003703b8062000106d410247044010000b200141d00a6a200041011067200141d00a6a200141b8066a108c01200141d00a6a106b220241e0036a200141b8086a200141b8066a102722001026200028020022030440200020033602040b2002106c20012802b8062200450d02200120003602bc060c020b41c90a106920055104402000106a200141b8066a200141d00a6a106b220341e0036a10272102200141b8086a101122002002108d01100f20002002108e01200028020c200041106a28020047044010000b200028020020002802041008200028020c22040440200020043602100b200228020022000440200220003602040b2003106c0c020b41d30a10692005510440200142003702bc062001200141b8066a4104723602b8062000106d410247044010000b200141d00a6a200041011067200141d00a6a200141b8066a108f01200141d00a6a106b2200200141b8086a200141b8066a102b10282000106c0c020b41da0a106920055104402000106a200141b8066a200141d00a6a106b22034188046a102b2102200141b8086a101122002002109001100f20002002109101200028020c200041106a28020047044010000b200028020020002802041008200028020c22020440200020023602100b2003106c0c020b41e10a10692005510440200141b8086a107b200141003a00c808200141003602c408200141c8086a21022000106d410447044010000b200141d00a6a200041011067200141d00a6a200141b8086a107c200141d00a6a2000410210672001200141d00a6a1087013602c408200141d00a6a200041031067200141d00a6a20021078200141d00a6a106b2100200141b8066a200141b8086a10121a2000200141b8066a20012802c40820012d00c808102c2000106c0c020b41f10a10692005510440200141003602a804200142003703a0042000106d410247044010000b200141d00a6a200041011067200141d00a6a200141a0046a109201200141d00a6a106b220341b0046a200141b8086a200141b8066a200141a0046a102e2200102e2202102d200228020022040440200220043602040b200028020022020440200020023602040b2003106c20012802a0042200450d02200120003602a4040c020b41fa0a106920055104402000106a200141b8066a200141d00a6a106b220341b0046a102e2102200141b8086a1011220020022802002002280204109301100f200020021010200028020c200041106a28020047044010000b200028020020002802041008200028020c22040440200020043602100b200228020022000440200220003602040b2003106c0c020b41830b10692005510440200141b8066a41f800107f1a200141b8066a10940121022000106d410247044010000b200141d00a6a200041011067200141d00a6a2002109501200141d00a6a106b220041c0056a200141b8086a20021030102f2000106c0c020b418c0b106920055104402000106a200141b8086a200141d00a6a106b220341c0056a10302102200141b8066a101122002002109601100f20002002109701200028020c200041106a28020047044010000b200028020020002802041008200028020c22020440200020023602100b2003106c0c020b41950b10692005510440200141b8066a10980121022000106d410247044010000b200141d00a6a200041011067200141d00a6a2002109901200141d00a6a106b220041d0066a200141b8086a2002103210312000106c0c020b419d0b106920055104402000106a200141b8066a200141d00a6a106b220341d0066a10322102200141b8086a101122002002109a01100f20002002109b01200028020c200041106a28020047044010000b200028020020002802041008200028020c22020440200020023602100b2003106c0c020b41a50b10692005510440200142003702bc062001200141b8066a4104723602b8062000106d410247044010000b200141d00a6a200041011067200141d00a6a200141b8066a109c01200141d00a6a106b2200200141b8086a200141b8066a103510332000106c0c020b41ac0b106920055104402000106a200141b8066a200141d00a6a106b220341f8066a10352102200141b8086a101122002002109d01100f20002002109e01200028020c200041106a28020047044010000b200028020020002802041008200028020c22020440200020023602100b2003106c0c020b41b30b10692005510440200141b8066a109f0121022000106d410247044010000b200141d00a6a200041011067200141d00a6a200210a001200141d00a6a106b2100200141206a200141b8066a41800210361a200141b8086a200141206a41800210361a20004190096a200141b8086a41800210361a2000106c0c020b41c00b106920055104402000106a200141a0026a200141d00a6a106b22024190096a41800210361a200141a0066a10112200200141a0026a10a101100f200141a0046a200141a0026a41800210361a200141b8066a200141a0046a41800210361a200141206a200141b8066a41800210361a200141b8086a200141206a41800210361a2000200141b8086a4180021058220028020c200041106a28020047044010000b200028020020002802041008200028020c22030440200020033602100b2002106c0c020b41cd0b10692005510440200141003602c0062001200141b8066a3602bc062001200141b8066a3602b8062000106d410247044010000b200141d00a6a200041011067200141d00a6a200141b8066a10a201200141d00a6a106b2200200141b8086a200141b8066a103922021037200210a3012000106c200141b8066a10a3010c020b41d50b106920055104402000106a200141b8066a200141d00a6a106b220341a80b6a10392102200141b8086a10112200200210a401100f2000200210a501200028020c200041106a28020047044010000b200028020020002802041008200028020c22040440200020043602100b200210a3012003106c0c020b41dd0b10692005510440200141b8086a10a60121022000106d410247044010000b200141d00a6a200041011067200141d00a6a200210a701200141d00a6a106b2100200141b0066a200141c8086a2802002202360200200141a8066a200141c0086a2903002205370300200120012903b80822063703a006200041d80b6a2006370300200041e00b6a2005370300200041e80b6a20023602002000106c0c020b41e80b10692005520d002000106a200141306a2200200141d00a6a106b220241e80b6a280000360200200141286a2203200241e00b6a2900003703002001200241d80b6a290000370320200141b8086a10112204200141206a10a801100f200141b0026a20002802002200360200200141a8026a200329030022053703002001200129032022063703a002200141a8046a2005370300200141b0046a2000360200200141a8066a2005370300200141b0066a2000360200200120063703a004200120063703a006200141c8066a2000360200200141c0066a2005370300200120063703b8062004200141b8066a41141058220028020c200041106a28020047044010000b200028020020002802041008200028020c22030440200020033602100b2002106c0c010b10000b200141c0166a24000b880101037f41f40b410136020041f80b2802002100034020000440034041fc0b41fc0b2802002201417f6a2202360200200141014845044041f40b4100360200200020024102746a22004184016a280200200041046a28020011030041f40b410136020041f80b28020021000c010b0b41fc0b412036020041f80b200028020022003602000c010b0b0b0d00200020012002411c10a9010bd00202067f017e230041106b220324002001280208220520024b0440200341086a200110cd0120012003280208200328020c10cb0136020c2003200110cd01410021052001027f410020032802002207450d001a410020032802042208200128020c2206490d001a200820062006417f461b210420070b360210200141146a2004360200200141003602080b200141106a210603402001280214210402402005200249044020040d01410021040b200020062802002004411410a9011a200341106a24000f0b2003200110cd0141002104027f410020032802002205450d001a410020032802042208200128020c2207490d001a200820076b2104200520076a0b210520012004360214200120053602102003200641002005200410cb0110cc012001200329030022093702102001200128020c2009422088a76a36020c2001200128020841016a22053602080c000b000b880102027f017e230041106b22012400200010aa0102400240200010ab01450d002000280204450d0020002802002d000041c001490d010b10000b200141086a200010ac01200128020c220041094f044010000b200128020821020340200004402000417f6a210020023100002003420886842103200241016a21020c010b0b200141106a240020030b3901027e42a5c688a1c89ca7f94b210103402000300000220250450440200041016a2100200142b383808080207e20028521010c010b0b20010b0e002000106d410147044010000b0bca2901097f230041406a22012400200042ddbe888dc5fcfca4987f370308200041003a0000200141286a1011220320002903081075200328020c200341106a28020047044010000b0240200328020022072003280204220810042205450d002001410036022020014200370318200141186a200510532007200820012802182204200128021c220620046b1005417f47044020002001200441016a20062004417f736a1066106e3a0010200521020b2004450d002001200436021c0b200328020c22040440200320043602100b2002450440200020002d00003a00100b41002102200041003b0118200041206a220442debe888dc5fcfca4987f370300200141286a1011220320042903001075200328020c200341106a28020047044010000b0240200328020022072003280204220810042205450d002001410036022020014200370318200141186a200510532007200820012802182204200128021c220620046b1005417f47044020002001200441016a20062004417f736a106610703b0128200521020b2004450d002001200436021c0b200328020c22040440200320043602100b2002450440200020002f01183b01280b4100210220004100360230200041386a220442dfbe888dc5fcfca4987f370300200141286a1011220320042903001075200328020c200341106a28020047044010000b0240200328020022072003280204220810042205450d002001410036022020014200370318200141186a200510532007200820012802182204200128021c220620046b1005417f47044020002001200441016a20062004417f736a10661072360240200521020b2004450d002001200436021c0b200328020c22040440200320043602100b2002450440200020002802303602400b20004200370348200041d0006a220242d9be888dc5fcfca4987f370300200141286a1011220320022903001075200328020c200341106a28020047044010000b0240200328020022072003280204220810042205450440410021040c010b410021042001410036022020014200370318200141186a200510532007200820012802182202200128021c220620026b1005417f47044020002001200241016a20062002417f736a10661068370358200521040b2002450d002001200236021c0b200328020c22020440200320023602100b2004450440200020002903483703580b200041e0006a10762109200041f0006a220242a7cea8ad82a0ff995b370300200041f8006a10762107200141286a1011220320022903001075200328020c200341106a28020047044010000b0240200328020022082003280204220610042205450440410021040c010b410021042001410036022020014200370318200141186a200510532008200620012802182202200128021c220620026b1005417f4704402001200241016a20062002417f736a106620071077200521040b2002450d002001200236021c0b200328020c22020440200320023602100b200445044020072009101f1a0b41002102200041003a00880120004190016a220442f4a2efb3f6e5b8ad03370300200141286a1011220320042903001075200328020c200341106a28020047044010000b0240200328020022072003280204220810042205450d002001410036022020014200370318200141186a200510532007200820012802182204200128021c220620046b1005417f4704402001200441016a20062004417f736a106620004198016a1078200521020b2004450d002001200436021c0b200328020c22040440200320043602100b2002450440200020002d0088013a0098010b200041003a00a001200041a8016a220342badda0b2f6c5fa8e033703002003200041b0016a10ad01450440200020002d00a0013a00b0010b200042003703b801200041c0016a4100360200200041b8016a10762109200041c8016a2202428aedabfdf7a698fe29370300200041d0016a220710761a200141286a1011220320022903001075200328020c200341106a28020047044010000b0240200328020022082003280204220610042205450440410021040c010b410021042001410036022020014200370318200141186a200510532008200620012802182202200128021c220620026b1005417f4704402001200241016a20062002417f736a10662007107c200521040b2002450d002001200236021c0b200328020c22020440200320023602100b200445044020072009101f1a0b41002102200041e0016a4124107f108001210920004188026a220442d4b7b1edebf7e3f66a37030020004190026a1080012107200141286a1011220320042903001075200328020c200341106a28020047044010000b0240200328020022082003280204220610042205450d002001410036022020014200370318200141186a200510532008200620012802182204200128021c220620046b1005417f4704402001200441016a20062004417f736a10662007108101200521020b2004450d002001200436021c0b200328020c22040440200320043602100b20024504402007200910220b200041003a00b802200041c0026a220342ccacbdb4f8a587a93d3703002003200041c8026a10ad01450440200020002d00b8023a00c8020b200041003b01d002200041d8026a220242cfacbdb4f8a587a93d370300200141286a1011220320022903001075200328020c200341106a28020047044010000b0240200328020022072003280204220810042205450440410021040c010b410021042001410036022020014200370318200141186a200510532007200820012802182202200128021c220620026b1005417f47044020002001200241016a20062002417f736a10661084013b01e002200521040b2002450d002001200236021c0b200328020c22020440200320023602100b2004450440200020002f01d0023b01e0020b41002102200041003602e802200041f0026a220442ceacbdb4f8a587a93d370300200141286a1011220320042903001075200328020c200341106a28020047044010000b0240200328020022072003280204220810042205450d002001410036022020014200370318200141186a200510532007200820012802182204200128021c220620046b1005417f47044020002001200441016a20062004417f736a10661087013602f802200521020b2004450d002001200436021c0b200328020c22040440200320043602100b2002450440200020002802e8023602f8020b200042003703800320004188036a220242c8acbdb4f8a587a93d370300200141286a1011220320022903001075200328020c200341106a28020047044010000b0240200328020022072003280204220810042205450440410021040c010b410021042001410036022020014200370318200141186a200510532007200820012802182202200128021c220620026b1005417f47044020002001200241016a20062002417f736a106610890137039003200521040b2002450d002001200236021c0b200328020c22020440200320023602100b20044504402000200029038003370390030b410021022000410036029803200041a0036a220442e2e780dbeae4fcabe100370300200141286a1011220320042903001075200328020c200341106a28020047044010000b0240200328020022072003280204220810042205450d002001410036022020014200370318200141186a200510532007200820012802182204200128021c220620046b1005417f47044020002001200441016a20062004417f736a106610723602a803200521020b2004450d002001200436021c0b200328020c22040440200320043602100b200245044020002000280298033602a8030b200042003703b003200041b8036a220242b3debf9dbddf9ca832370300200141286a1011220320022903001075200328020c200341106a28020047044010000b0240200328020022072003280204220810042205450440410021040c010b410021042001410036022020014200370318200141186a200510532007200820012802182202200128021c220620026b1005417f47044020002001200241016a20062002417f736a106610683703c003200521040b2002450d002001200236021c0b200328020c22020440200320023602100b2004450440200020002903b0033703c0030b200042003702c80341002102200041e8036a4100360200200041e0036a22074200370200200041d8036a2204429fe6c89bc186c5be1d370300200041d0036a4100360200200141286a1011220320042903001075200328020c200341106a28020047044010000b0240200328020022082003280204220610042205450d002001410036022020014200370318200141186a200510532008200620012802182204200128021c220920046b1005417f4704402001200441016a20092004417f736a10662007108c01200521020b2004450d002001200436021c0b200328020c22040440200320043602100b20024504402007200041c8036a10260b200041f4036a220342003702002000418c046a2202420037020020004180046a2204428cbcadf0bacdb08975370300200020033602f00320004188046a22072002360200200141286a1011220320042903001075200328020c200341106a28020047044010000b0240200328020022082003280204220610042205450440410021040c010b410021042001410036022020014200370318200141186a200510532008200620012802182202200128021c220920026b1005417f4704402001200241016a20092002417f736a10662007108f01200521040b2002450d002001200236021c0b200328020c22020440200320023602100b20044504402007200041f0036a10290b200042003702980441002102200041b8046a4100360200200041b0046a22074200370200200041a8046a220442bd8ce2969cacfba4b07f370300200041a0046a4100360200200141286a1011220320042903001075200328020c200341106a28020047044010000b0240200328020022082003280204220610042205450d002001410036022020014200370318200141186a200510532008200620012802182204200128021c220920046b1005417f4704402001200441016a20092004417f736a10662007109201200521020b2004450d002001200436021c0b200328020c22040440200320043602100b2002450440200720004198046a102d0b41002102200041c0046a41f800107f1094012109200041b8056a2204429fa88ce0a0829ecea47f370300200041c0056a1094012107200141286a1011220320042903001075200328020c200341106a28020047044010000b0240200328020022082003280204220610042205450d002001410036022020014200370318200141186a200510532008200620012802182204200128021c220620046b1005417f4704402001200441016a20062004417f736a10662007109501200521020b2004450d002001200436021c0b200328020c22040440200320043602100b200245044020072009102f0b200041b8066a1098012109200041c8066a220242bcf8d4f484c7a18d807f370300200041d0066a1098012107200141286a1011220320022903001075200328020c200341106a28020047044010000b0240200328020022082003280204220610042205450440410021040c010b410021042001410036022020014200370318200141186a200510532008200620012802182202200128021c220620026b1005417f4704402001200241016a20062002417f736a10662007109901200521040b2002450d002001200236021c0b200328020c22020440200320023602100b20044504402007200910310b200041e4066a22034200370200200041fc066a22024200370200200041f0066a220442eafdbbb690ac81edca00370300200020033602e006200041f8066a22072002360200200141286a1011220320042903001075200328020c200341106a28020047044010000b0240200328020022082003280204220610042205450440410021040c010b410021042001410036022020014200370318200141186a200510532008200620012802182202200128021c220920026b1005417f4704402001200241016a20092002417f736a10662007109c01200521040b2002450d002001200236021c0b200328020c22020440200320023602100b20044504402007200041e0066a10340b20004188076a2209109f011a20004188096a220242d0b4afbcbf988ce0b77f37030020004190096a109f012107200141286a1011220320022903001075200328020c200341106a28020047044010000b0240200328020022082003280204220610042205450440410021040c010b410021042001410036022020014200370318200141186a200510532008200620012802182202200128021c220620026b1005417f4704402001200241016a20062002417f736a1066200710a001200521040b2002450d002001200236021c0b200328020c22020440200320023602100b20044504402007200941800210361a0b41002104200041b00b6a4100360200200041ac0b6a200041a80b6a2202360200200041a00b6a220542f4ffce959b97c9c1d500370300200041980b6a4100360200200041940b6a200041900b6a2207360200200020073602900b20022002360200200141286a1011220320052903001075200328020c200341106a28020047044010000b0240200328020022062003280204220910042208450d002001410036022020014200370318200141186a200810532006200920012802182205200128021c220620056b1005417f4704402001200541016a20062005417f736a1066200210a201200821040b2005450d002001200536021c0b200328020c22050440200320053602100b20044504402002200710380b200041b80b6a220710a6011a200041d00b6a220242affad78bbfdecaa6f300370300200041d80b6a10a6012104200141286a1011220320022903001075200328020c200341106a28020047044010000b0240200328020022062003280204220910042208450440410021050c010b410021052001410036022020014200370318200141186a200810532006200920012802182202200128021c220620026b1005417f4704402001200241016a20062002417f736a1066200410a701200821050b2002450d002001200236021c0b200328020c22020440200320023602100b200545044020042007290300370300200441106a200741106a280200360200200441086a200741086a2903003703000b200141406b240020000b953102087f027e230041c0086b22052400200541c0066a10112201200041d00b6a22022903001074100f200120022903001075200041d80b6a2102200128020c200141106a28020047044010000b2001280204210720012802002106200541c0046a10112104200210a8012108200420054180026a10ae01220310af012004200820032802046a20032802006b100f200541a0026a200241106a280000220836020020054198026a200241086a290000220937030020052002290000220a37039002200541b0026a2009370300200541b8026a2008360200200541086a2009370300200541106a20083602002005200a3703a8022005200a370300200541d0026a2008360200200541c8026a20093703002005200a3703c00202402004200541c0026a41141058220228020c200241106a280200460440200241046a2104200228020021080c010b200241046a2104100020022802002108200228020c2002280210460d0010000b20062007200820042802001006200328020022040440200320043602040b200228020c22030440200220033602100b200128020c22020440200120023602100b200541c0066a10112202200041a00b6a22012903001074100f200220012903001075200041a80b6a2104200228020c200241106a28020047044010000b2002280204210820022802002107200541c0046a10112101200410a40121062001200541c0026a10ae01220310af012001200620032802046a20032802006b100f2001200410a5010240200128020c200141106a280200460440200141046a2104200128020021060c010b200141046a2104100020012802002106200128020c2001280210460d0010000b20072008200620042802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200041a80b6a10a301200041900b6a10a301200541a8026a1011220120004188096a22022903001074100f20012002290300107520004190096a2104200128020c200141106a28020047044010000b200128020421082001280200210720054190026a10112102200410a1012106200220054180026a10ae01220310af012002200620032802046a20032802006b100f200520044180021036220541c0026a200541800210361a200541c0046a200541c0026a41800210361a200541c0066a200541c0046a41800210361a02402002200541c0066a4180021058220228020c200241106a280200460440200241046a2104200228020021060c010b200241046a2104100020022802002106200228020c2002280210460d0010000b20072008200620042802001006200328020022040440200320043602040b200228020c22030440200220033602100b200128020c22020440200120023602100b200541c0066a10112202200041f0066a22012903001074100f200220012903001075200041f8066a2104200228020c200241106a28020047044010000b2002280204210820022802002107200541c0046a101121012004109d0121062001200541c0026a10ae01220310af012001200620032802046a20032802006b100f20012004109e010240200128020c200141106a280200460440200141046a2104200128020021060c010b200141046a2104100020012802002106200128020c2001280210460d0010000b20072008200620042802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a10112202200041c8066a22012903001074100f200220012903001075200041d0066a2104200228020c200241106a28020047044010000b2002280204210820022802002107200541c0046a101121012004109a0121062001200541c0026a10ae01220310af012001200620032802046a20032802006b100f20012004109b010240200128020c200141106a280200460440200141046a2104200128020021060c010b200141046a2104100020012802002106200128020c2001280210460d0010000b20072008200620042802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a10112202200041b8056a22012903001074100f200220012903001075200041c0056a2104200228020c200241106a28020047044010000b2002280204210820022802002107200541c0046a10112101200410960121062001200541c0026a10ae01220310af012001200620032802046a20032802006b100f200120041097010240200128020c200141106a280200460440200141046a2104200128020021060c010b200141046a2104100020012802002106200128020c2001280210460d0010000b20072008200620042802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a10112202200041a8046a22012903001074100f200220012903001075200041b0046a2104200228020c200241106a28020047044010000b2002280204210820022802002107200541c0046a1011210120002802b004200041b4046a28020010930121062001200541c0026a10ae01220310af012001200620032802046a20032802006b100f2001200410100240200128020c200141106a280200460440200141046a2104200128020021060c010b200141046a2104100020012802002106200128020c2001280210460d0010000b20072008200620042802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200041b0046a28020022010440200041b4046a20013602000b200028029804220104402000419c046a20013602000b200541c0066a1011220220004180046a22012903001074100f20022001290300107520004188046a2104200228020c200241106a28020047044010000b2002280204210820022802002107200541c0046a10112101200410900121062001200541c0026a10ae01220310af012001200620032802046a20032802006b100f200120041091010240200128020c200141106a280200460440200141046a2104200128020021060c010b200141046a2104100020012802002106200128020c2001280210460d0010000b20072008200620042802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a10112202200041d8036a22012903001074100f200220012903001075200041e0036a2104200228020c200241106a28020047044010000b2002280204210820022802002107200541c0046a101121012004108d0121062001200541c0026a10ae01220310af012001200620032802046a20032802006b100f20012004108e010240200128020c200141106a280200460440200141046a2104200128020021060c010b200141046a2104100020012802002106200128020c2001280210460d0010000b20072008200620042802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200041e0036a28020022010440200041e4036a20013602000b20002802c80322010440200041cc036a20013602000b200541c0046a10112202200041b8036a22012903001074100f200220012903001075200228020c200241106a28020047044010000b2002280204210420022802002108200541c0026a10112101200541d8066a4100360200200541d0066a4200370300200541c8066a4200370300200542003703c006200541c0066a20002903c00310b00120052802c0062107200541c0066a41047210152001200541c0066a10ae01220310af012001200720032802046a20032802006b100f200120002903c00310750240200128020c200141106a280200460440200141046a2107200128020021060c010b200141046a2107100020012802002106200128020c2001280210460d0010000b20082004200620072802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0046a10112202200041a0036a22012903001074100f200220012903001075200228020c200241106a28020047044010000b2002280204210420022802002108200541c0026a10112101200541d8066a4100360200200541d0066a4200370300200541c8066a4200370300200542003703c006200541c0066a20002802a803101920052802c0062107200541c0066a41047210152001200541c0066a10ae01220310af012001200720032802046a20032802006b100f200120002802a803101a0240200128020c200141106a280200460440200141046a2107200128020021060c010b200141046a2107100020012802002106200128020c2001280210460d0010000b20082004200620072802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a1011220220004188036a22012903001074100f200220012903001075200228020c200241106a28020047044010000b2002280204210420022802002108200541c0046a10112101200029039003108a0121072001200541c0026a10ae01220310af012001200720032802046a20032802006b100f2001200029039003108b010240200128020c200141106a280200460440200141046a2107200128020021060c010b200141046a2107100020012802002106200128020c2001280210460d0010000b20082004200620072802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a10112202200041f0026a22012903001074100f200220012903001075200228020c200241106a28020047044010000b2002280204210420022802002108200541c0046a1011210120002802f80210880121072001200541c0026a10ae01220310af012001200720032802046a20032802006b100f200120002802f8021086010240200128020c200141106a280200460440200141046a2107200128020021060c010b200141046a2107100020012802002106200128020c2001280210460d0010000b20082004200620072802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a10112202200041d8026a22012903001074100f200220012903001075200228020c200241106a28020047044010000b2002280204210420022802002108200541c0046a1011210120002f01e00210850121072001200541c0026a10ae01220310af012001200720032802046a20032802006b100f200120002e01e0021086010240200128020c200141106a280200460440200141046a2107200128020021060c010b200141046a2107100020012802002106200128020c2001280210460d0010000b20082004200620072802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200041c0026a200041c8026a10b101200541c0066a1011220220004188026a22012903001074100f20022001290300107520004190026a2104200228020c200241106a28020047044010000b2002280204210820022802002107200541c0046a10112101200410820121062001200541c0026a10ae01220310af012001200620032802046a20032802006b100f200120041083010240200128020c200141106a280200460440200141046a2104200128020021060c010b200141046a2104100020012802002106200128020c2001280210460d0010000b20072008200620042802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a10112202200041c8016a22012903001074100f200220012903001075200041d0016a2104200228020c200241106a28020047044010000b2002280204210820022802002107200541c0046a101121012004107d21062001200541c0026a10ae01220310af012001200620032802046a20032802006b100f20012004107e0240200128020c200141106a280200460440200141046a2104200128020021060c010b200141046a2104100020012802002106200128020c2001280210460d0010000b20072008200620042802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200041a8016a200041b0016a10b101200541c0066a1011220220004190016a22012903001074100f200220012903001075200228020c200241106a28020047044010000b2002280204210420022802002108200541c0046a1011210120002d009801106f21072001200541c0026a10ae01220310af012001200720032802046a20032802006b100f200120002d009801101a0240200128020c200141106a280200460440200141046a2107200128020021060c010b200141046a2107100020012802002106200128020c2001280210460d0010000b20082004200620072802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a10112201200041f0006a22022903001074100f200120022903001075200041f8006a2104200128020c200141106a28020047044010000b2001280204210820012802002107200541c0046a101121022004105221062002200541c0026a10ae01220310af012002200620032802046a20032802006b100f024020022005200410121017220228020c200241106a280200460440200241046a2104200228020021060c010b200241046a2104100020022802002106200228020c2002280210460d0010000b20072008200620042802001006200328020022040440200320043602040b200228020c22030440200220033602100b200128020c22020440200120023602100b200541c0066a10112202200041d0006a22012903001074100f200220012903001075200228020c200241106a28020047044010000b2002280204210420022802002108200541c0046a101121012000290358107421072001200541c0026a10ae01220310af012001200720032802046a20032802006b100f2001200029035810750240200128020c200141106a280200460440200141046a2107200128020021060c010b200141046a2107100020012802002106200128020c2001280210460d0010000b20082004200620072802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a10112202200041386a22012903001074100f200220012903001075200228020c200241106a28020047044010000b2002280204210420022802002108200541c0046a101121012000280240107321072001200541c0026a10ae01220310af012001200720032802046a20032802006b100f20012000280240101a0240200128020c200141106a280200460440200141046a2107200128020021060c010b200141046a2107100020012802002106200128020c2001280210460d0010000b20082004200620072802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a10112202200041206a22012903001074100f200220012903001075200228020c200241106a28020047044010000b2002280204210420022802002108200541c0046a1011210120002f0128107121072001200541c0026a10ae01220310af012001200720032802046a20032802006b100f200120002f0128101a0240200128020c200141106a280200460440200141046a2107200128020021060c010b200141046a2107100020012802002106200128020c2001280210460d0010000b20082004200620072802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a1011220220002903081074100f200220002903081075200228020c200241106a28020047044010000b2002280204210420022802002108200541c0046a1011210120002d0010106f21072001200541c0026a10ae01220310af012001200720032802046a20032802006b100f200120002d0010101a0240200128020c200141106a280200460440200141046a2107200128020021060c010b200141046a2107100020012802002106200128020c2001280210460d0010000b20082004200620072802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0086a24000b2601017f02402000280204450d0020002802002d000041c001490d00200010b20121010b20010b800101037f230041106b22012400200010aa0102400240200010ab01450d002000280204450d0020002802002d000041c001490d010b10000b200141086a200010ac01200128020c220041024f044010000b200128020821020340200004402000417f6a210020022d00002103200241016a21020c010b0b200141106a240020030b5801027f230041206b22012400200141186a4100360200200141106a4200370300200141086a42003703002001420037030020012000ad42ff018342001056210020012802002102200041046a1015200141206a240020020b8b0101037f230041106b22012400200010aa0102400240200010ab01450d002000280204450d0020002802002d000041c001490d010b10000b200141086a200010ac01200128020c220041034f044010000b200128020821030340200004402000417f6a210020032d00002002410874722102200341016a21030c010b0b200141106a2400200241ffff03710b5401017f230041206b22012400200141186a4100360200200141106a4200370300200141086a4200370300200142003703002001200041ffff037110192001280200210020014104721015200141206a240020000b860101037f230041106b22012400200010aa0102400240200010ab01450d002000280204450d0020002802002d000041c001490d010b10000b200141086a200010ac01200128020c220041054f044010000b200128020821030340200004402000417f6a210020032d00002002410874722102200341016a21030c010b0b200141106a240020020b4f01017f230041206b22012400200141186a4100360200200141106a4200370300200141086a4200370300200142003703002001200010192001280200210020014104721015200141206a240020000b5001027f230041206b22012400200141186a4100360200200141106a4200370300200141086a4200370300200142003703002001200010b0012001280200210220014104721015200141206a240020020b0a0020002001420010590b1a0020004200370200200041086a4100360200200010b30120000ba40201057f230041206b22022400024002402000280204044020002802002d000041c001490d010b200241086a10761a0c010b200241186a200010ac01200010b40121030240024002400240200228021822000440200228021c220520034f0d010b41002100200241106a410036020020024200370308410021050c010b200241106a4100360200200242003703082000200520032003417f461b22046a21052004410a4b0d010b200220044101743a0008200241086a41017221030c010b200441106a4170712206103a21032002200436020c20022006410172360208200220033602100b03402000200546450440200320002d00003a0000200341016a2103200041016a21000c010b0b200341003a00000b2001200241086a10b501200241206a24000b0e0020012000106e4100473a00000b4401027f230041f00b6b220224002000106d410247044010000b2002200041011067200210b60121002002106b21032002200020011100002003106c200241f00b6a24000b7b01027f230041900c6b220224002000106a200241086a106b2103200241086a20011101002100200241f80b6a10112201200010b701100f20012000108601200128020c200141106a28020047044010000b200128020020012802041008200128020c22000440200120003602100b2003106c200241900c6a24000b180020004200370200200041086a4100360200200010761a0b2801017f230041206b22022400200241086a200041001067200241086a20011077200241206a24000b5001017f230041206b22012400200141186a4100360200200141106a4200370300200141086a4200370300200142003703002001200010b8012001280200210020014104721015200141206a240020000b6e01027f230041406a220224002000410110162100200241386a4100360200200241306a4200370300200241286a420037030020024200370320200241206a200241106a200110121014210320002002280220100f200020022001101210171a200341046a1015200241406b24000be10201027f02402001450d00200041003a0000200020016a2203417f6a41003a000020014103490d00200041003a0002200041003a00012003417d6a41003a00002003417e6a41003a000020014107490d00200041003a00032003417c6a41003a000020014109490d002000410020006b41037122026a220341003602002003200120026b417c7122026a2201417c6a410036020020024109490d002003410036020820034100360204200141786a4100360200200141746a410036020020024119490d002003410036021820034100360214200341003602102003410036020c200141706a41003602002001416c6a4100360200200141686a4100360200200141646a41003602002002200341047141187222026b2101200220036a2102034020014120490d0120024200370300200241186a4200370300200241106a4200370300200241086a4200370300200241206a2102200141606a21010c000b000b20000b1900200010761a2000410c6a10761a200041186a10761a20000b5601017f230041206b22022400200241086a200041001067200241086a2001107c200241086a200041011067200241086a2001410c6a1077200241086a200041021067200241086a200141186a1077200241206a24000b7a01027f230041406a22012400200141186a4100360200200141106a4200370300200141086a4200370300200142003703002001410010132202200010b8012002200141306a2000410c6a10121014200141206a200041186a1012101441011013210020012802002102200041046a1015200141406b240020020ba30101047f230041e0006b220224002000410310162100200241d8006a4100360200200241d0006a4200370300200241c8006a420037030020024200370340200241406b200110b801200241406b200241306a2001410c6a220310121014200241206a200141186a220410121014210520002002280240100f20002001107e2000200241106a20031012101720022004101210171a200541046a1015200241e0006a24000b3902017f017e230041106b220124002001200010b90120012903002102200141106a2400420020024201837d200242018885a74110744110750b6202027f017e230041206b22012400200141186a4100360200200141106a4200370300200141086a42003703002001420037030020012000ad42308622034230872003423f8710ba01210020012802002102200041046a1015200141206a240020020b1301017e20002001ac22022002423f8710bb010b3302017f017e230041106b220124002001200010b90120012903002102200141106a2400420020024201837d200242018885a70b5201027f230041206b22012400200141186a4100360200200141106a4200370300200141086a4200370300200142003703002001200010bc01210020012802002102200041046a1015200141206a240020020b4202017f027e230041106b220124002001200010b901200141086a290300210320012903002102200141106a2400420020024201837d2003423f86200242018884850b5701037f230041206b22012400200141186a4100360200200141106a4200370300200141086a420037030020014200370300200120002000423f8710ba01210220012802002103200241046a1015200141206a240020030b0e00200020012001423f8710bb010bb10201047f230041d0006b22022400024002402000280204450d0020002802002d000041c001490d002000106d21032001280208200128020022046b4101752003490440200120022003200128020420046b410175200141086a10bd01220310be01200310bf010b200241286a200010c001200241186a200010c101200141086a21050340200228022c200228021c46044020022802302002280220460d030b2002200241286a10c2012002107021030240200128020422002001280208490440200020033b01002001200041026a3602040c010b200241386a2001200020012802006b410175220041016a104f2000200510bd0121002002280240220420033b01002002200441026a3602402001200010be01200010bf010b200241286a10c3010c000b000b10000b200241d0006a24000b9c0101037f230041206b22012400200141186a4100360200200141106a4200370300200141086a420037030020014200370300024020002802002000280204460440200110c4010c010b200141001013210220002802042103200028020021000340200020034604402002410110131a05200220002f01001019200041026a21000c010b0b0b2001280200210020014104721015200141206a240020000b4301017f2000200128020420012802006b410175101621022001280204210020012802002101034020002001470440200220012f0100101a200141026a21010c010b0b0be20201057f23004190016b22022400024002402000280204450d0020002802002d000041c001490d00200241c8006a200010c001200241386a200010c101200241146a21040340200228024c200228023c46044020022802502002280240460d030b200241206a200241c8006a10c201200241086a10762100200410762105200241206a10c501410247044010000b20024180016a10762103200241e8006a200241206a41001067200241e8006a200310772000200310b501200241d8006a10762103200241e8006a200241206a41011067200241e8006a200310772005200310b5012001200241e8006a2000103d22062802004504404128103a22032002290308370210200341186a200241106a280200360200200010b301200341246a200441086a2802003602002003411c6a2004290200370200200510b3012001200228026820062003103f0b200241c8006a10c3010c000b000b10000b20024190016a24000bd00101047f230041e0006b22012400200141206a4100360200200141186a4200370300200141106a42003703002001420037030802402000280208450440200141086a10c4010c010b200041046a2103200141086a410010132102200141346a2104200028020021000340200020034604402002410110131a05200141286a200041106a104b200241001013200141d0006a200141286a10121014200141406b200410121014410110131a2000102a21000c010b0b0b20012802082100200141086a4104721015200141e0006a240020000b6101027f230041206b220224002000200128020810162103200141046a210020012802002101034020002001460440200241206a240005200341021016200241106a200141106a1012101720022001411c6a101210171a2001102a21010c010b0b0bce0101037f230041206b22022400024002402000280204044020002802002d000041c001490d010b20024100360208200242003703000c010b200241186a200010ac0120022802182103200241106a200010ac0120022802102104200010b40121002002410036020820024200370300200020046a20036b2200450d0020022000104520004101480d002002200228020420032000103620006a3602040b2001280200044020014100360208200142003702000b2001200228020036020020012002290204370204200241206a24000b5301017f230041206b22022400200241186a4100360200200241106a4200370300200241086a420037030020024200370300200220002001100e210020022802002101200041046a1015200241206a240020010b2c01037f200041f8006a21022000210103402001107621032001410c6a21012003410c6a2002470d000b20000b6101037f230041306b22022400200010c501410a47044010000b03402003410a460440200241306a240005200241206a10762104200241086a200020031067200241086a200410772001200410b5012001410c6a2101200341016a21030c010b0b0b800101037f230041306b22012400200141186a4100360200200141106a4200370300200141086a42003703002001420037030020014100101321030340200241f800464504402003200141206a200020026a101210141a2002410c6a21020c010b0b200341011013210220012802002103200241046a1015200141306a240020030b4401027f230041106b220224002000410a10162103410021000340200041f800460440200241106a24000520032002200020016a101210171a2000410c6a21000c010b0b0b1000200010761a2000410036020c20000b5d01027f230041306b22022400200010c501410247044010000b200241206a10762103200241086a200041001067200241086a200310772001200310b501200241086a2000410110672001200241086a10870136020c200241306a24000b7301027f230041406a22012400200141286a4100360200200141206a4200370300200141186a4200370300200142003703102001200010322100200141106a41001013200141306a200010121014200028020c10bc0141011013210020012802102102200041046a1015200141406b240020020b2a01017f230041106b220224002000410210162002200110121017200128020c108601200241106a24000bd70101047f230041d0006b22022400024002402000280204450d0020002802002d000041c001490d00200241406b200010c001200241306a200010c101200241106a210403402002280244200228023446044020022802482002280238460d030b200241186a200241406b10c201200241186a200241086a1076220010772001200241cc006a2000103d2205280200450440411c103a22032002290308370210200341186a2004280200360200200010b3012001200228024c20052003103f0b200241406b10c3010c000b000b10000b200241d0006a24000b9e0101037f230041306b22012400200141186a4100360200200141106a4200370300200141086a42003703002001420037030002402000280208450440200110c4010c010b200041046a21032001410010132102200028020021000340200020034604402002410110131a052002200141206a200041106a101210141a2000102a21000c010b0b0b2001280200210020014104721015200141306a240020000b4f01027f230041106b220224002000200128020810162103200141046a210020012802002101034020002001460440200241106a24000520032002200141106a101210171a2001102a21010c010b0b0b2601017f0340200141800246450440200020016a41003a0000200141016a21010c010b0b20000b990101027f23004190046b22022400200010aa0120024188046a200010ac01200228028c042103024002402000280204450d0020034180024b0d0020002802002d000041c001490d010b10000b20024188026a109f0120034180022003418002491b22006b4180026a200228028804200010361a200241086a20024188026a41800210361a2001200241086a41800210361a20024190046a24000bc00101037f230041a0086b2201240020014198026a410036020020014190026a420037030020014188026a42003703002001420037038002200120004180021036220041a0026a200041800210361a200041a0046a200041a0026a41800210361a200041a0066a200041a0046a41800210361a41012103024003402002418002460d01200041a0066a20026a2101200241016a210220012d0000450d000b41830221030b200020033602800220004180026a4104721015200041a0086a240020030bec0101037f230041d0006b22022400024002402000280204450d0020002802002d000041c001490d00200241406b200010c001200241306a200010c101200241106a210403402002280244200228023446044020022802482002280238460d030b200241186a200241406b10c201200241186a200241086a1076220310774114103a2200410036020020002002290308370208200041106a2004280200360200200310b30120002001360204200128020021032001200036020020002003360200200320003602042001200128020841016a360208200241406b10c3010c000b000b10000b200241d0006a24000b4d01037f02402000280208450d00200028020422012802002202200028020022032802043602042000410036020820032802042002360200034020002001460d01200128020421010c000b000b0b9d0101037f230041306b22012400200141186a4100360200200141106a4200370300200141086a42003703002001420037030002402000280208450440200110c4010c010b200041046a2102200141001013210303402002280200220220004604402003410110131a052003200141206a200241086a101210141a200241046a21020c010b0b0b2001280200210220014104721015200141306a240020020b4e01027f230041106b22032400200141046a210220002001280208101621000340200228020022022001460440200341106a24000520002003200241086a101210171a200241046a21020c010b0b0b2501017f03402001411446450440200020016a41003a0000200141016a21010c010b0b20000bbe0102027f027e230041406a22022400200010aa01200241386a200010ac01200228023c2103024002402000280204450d00200341144b0d0020002802002d000041c001490d010b10000b200241206a10a6012003411420034114491b22006b41146a2002280238200010361a200241186a200241306a2802002200360200200241106a200241286a2903002204370300200220022903202205370308200141106a2000360000200141086a200437000020012005370000200241406b24000b850202037f027e23004180016b22012400200141306a4100360200200141286a4200370300200141206a4200370300200141086a200041086a2900002204370300200141106a200041106a280000220236020020014200370318200120002900002205370300200141406b2004370300200141c8006a2002360200200141d8006a2004370300200141e0006a20023602002001200537033820012005370350200141f8006a2002360200200141f0006a200437030020012005370368410121020240034020034114460d01200141e8006a20036a2100200341016a210320002d0000450d000b411521020b20012002360218200141186a410472101520014180016a240020020b750020004200370210200042ffffffff0f370208200020023602042000200136020002402003410871450d00200010c90120024f0d002003410471044010000c010b200042003702000b02402003411071450d00200010c90120024d0d0020034104710440100020000f0b200042003702000b20000b4101017f200028020445044010000b0240200028020022012d0000418101470d00200028020441014d047f100020002802000520010b2c00014100480d0010000b0b990101037f200028020445044041000f0b200010aa01200028020022022c0000220141004e044020014100470f0b027f4101200141807f460d001a200141ff0171220341b7014d0440200028020441014d047f100020002802000520020b2d00014100470f0b4100200341bf014b0d001a2000280204200141ff017141ca7e6a22014d047f100020002802000520020b20016a2d00004100470b0bd60101047f200110b4012204200128020422024b04401000200128020421020b200128020021052000027f02400240200204404100210120052c00002203417f4a0d01027f200341ff0171220141bf014d04404100200341ff017141b801490d011a200141c97e6a0c010b4100200341ff017141f801490d001a200141897e6a0b41016a21010c010b4101210120050d000c010b41002103200120046a20024b0d0020022001490d00410020022004490d011a200120056a2103200220016b20042004417f461b0c010b41000b360204200020033602000bc20101057f230041406a22022400200241286a1011220320002903001075200328020c200341106a28020047044010000b02402003280200220020032802042205100422064504400c010b2002410036022020024200370318200241186a200610532000200520022802182200200228021c220520006b1005417f47044020012002200041016a20052000417f736a106610b6013a0000200621040b2000450d002002200036021c0b200328020c22000440200320003602100b200241406b240020040b30002000410036020820004200370200200041011045200028020441fe013a00002000200028020441016a36020420000b6101037f200028020c200041106a28020047044010000b200028020422022001280204200128020022036b22016a220420002802084b047f20002004105720002802040520020b20002802006a2003200110361a2000200028020420016a3602040b0b0020002001420010561a0b8e0201067f230041406a22042400200441286a1011220220002903001074100f200220002903001075200228020c200241106a28020047044010000b2002280204210620022802002107200441106a1011210020012d000010b70121052000200410ae01220310af012000200520032802046a20032802006b100f200020012c00001086010240200028020c200041106a280200460440200041046a2101200028020021050c010b200041046a2101100020002802002105200028020c2000280210460d0010000b20072006200520012802001006200328020022010440200320013602040b200028020c22030440200020033602100b200228020c22000440200220003602100b200441406b24000b820101047f230041106b2201240002402000280204450d0020002802002d000041c001490d00200141086a200010cd01200128020c210003402000450d0120014100200128020822032003200010cb0122046a20034520002004497222031b3602084100200020046b20031b2100200241016a21020c000b000b200141106a240020020b2201017f03402001410c470440200020016a4100360200200141046a21010c010b0b0b800301037f200028020445044041000f0b200010aa0141012102024020002802002c00002201417f4a0d00200141ff0171220341b7014d0440200341807f6a0f0b02400240200141ff0171220141bf014d0440024020002802042201200341c97e6a22024d047f100020002802040520010b4102490d0020002802002d00010d0010000b200241054f044010000b20002802002d000145044010000b4100210241b7012101034020012003460440200241384f0d030c0405200028020020016a41ca7e6a2d00002002410874722102200141016a21010c010b000b000b200141f7014d0440200341c07e6a0f0b024020002802042201200341897e6a22024d047f100020002802040520010b4102490d0020002802002d00010d0010000b200241054f044010000b20002802002d000145044010000b4100210241f701210103402001200346044020024138490d0305200028020020016a418a7e6a2d00002002410874722102200141016a21010c010b0b0b200241ff7d490d010b10000b20020b5c00024020002d0000410171450440200041003b01000c010b200028020841003a00002000410036020420002d0000410171450d00200041003602000b20002001290200370200200041086a200141086a280200360200200110b3010b3902017f017e230041106b220124002001200010b90120012903002102200141106a2400420020024201837d200242018885a74118744118750b6202027f017e230041206b22012400200141186a4100360200200141106a4200370300200141086a42003703002001420037030020012000ad42388622034238872003423f8710ba01210020012802002102200041046a1015200141206a240020020b2701017f230041106b220224002000410010132002200110121014410110131a200241106a24000ba10102027f027e230041106b22022400200110aa0102400240200110ab01450d002001280204450d0020012802002d000041c001490d010b10000b200241086a200110ac01200228020c220141114f044010000b20022802082103034020010440200542088620044238888421052001417f6a210120033100002004420886842104200341016a21030c010b0b2000200437030020002005370308200241106a24000b2301017e20002002423f87220320014201868520024201862001423f888420038510560b2301017e20002002423f87220320014201868520024201862001423f888420038510590b1301017e20002001ac22022002423f8710ba010b4c01017f2000410036020c200041106a2003360200200104402001104d21040b200020043602002000200420024101746a22023602082000200420014101746a36020c2000200236020420000b870101037f200120012802042000280204200028020022046b22036b2202360204200341004a044020022004200310361a200128020421020b200028020021032000200236020020012003360204200028020421022000200128020836020420012002360208200028020821022000200128020c3602082001200236020c200120012802043602000b2b01027f200028020821012000280204210203402001200247044020002001417e6a22013602080c010b0b0b0b0020002001410110c6010b0b0020002001410010c6010b170020002001280204200141086a280200411c10a9011a0bb70102057f017e230041106b22032400200041046a210102402000280200220204402001280200220504402005200041086a2802006a21040b20002004360204200041086a2002360200200341086a200141002004200210cb0110cc0120002003290308220637020420004100200028020022012006422088a76b2202200220014b1b3602000c010b200020012802002201047f2001200041086a2802006a0541000b360204200041086a41003602000b200341106a24000b3901017f027f200041186a28020022010440200041086a280200200041146a280200200110550c010b20000b2201200128020041016a3602000b220002402000280204044020002802002d000041bf014b0d010b10000b200010b2010be70101037f230041106b2204240020004200370200200041086a410036020020012802042103024002402002450440200321020c010b410021022003450d002003210220012802002d000041c001490d00200441086a200110cd0120004100200428020c220120042802082202200110cb0122032003417f461b20024520012003497222031b220536020820004100200220031b3602042000200120056b3602000c010b20012802002103200128020421012000410036020020004100200220016b20034520022001497222021b36020820004100200120036a20021b3602040b200441106a24000b3501017f230041106b220041908c0436020c41800c200028020c41076a417871220036020041840c200036020041880c3f003602000b10002002044020002001200210361a0b0b3001017f200028020445044041000f0b4101210120002802002c0000417f4c047f200010ca01200010b4016a0520010b0b5b00027f027f41002000280204450d001a410020002802002c0000417f4a0d011a20002802002d0000220041bf014d04404100200041b801490d011a200041c97e6a0c010b4100200041f801490d001a200041897e6a0b41016a0b0b2901017f230041206b22022400200241086a20002001411410a90110c9012100200241206a240020000b5b01027f2000027f0240200128020022054504400c010b200220036a200128020422014b0d0020012002490d00410020012003490d011a200220056a2104200120026b20032003417f461b0c010b41000b360204200020043602000b2401017f200110b401220220012802044b044010000b20002001200110ca01200210cc010b2f002000200210cf01200028020020002802046a2001200210361a2000200028020420026a3602042000200310d0010b1b00200028020420016a220120002802084b04402000200110570b0b830201047f02402001450d00034020002802102202200028020c460d01200241786a28020020014904401000200028021021020b200241786a2203200328020020016b220136020020010d012000200336021020004101200028020422032002417c6a28020022016b22021054220441016a20024138491b220520036a10d101200120002802006a220320056a2003200210490240200241374d0440200028020020016a200241406a3a00000c010b200441f7016a220341ff014d0440200028020020016a20033a00002000280200200120046a6a210103402002450d02200120023a0000200241087621022001417f6a21010c000b000b10000b410121010c000b000b0b0f00200020011057200020013602040b26002000410110cf01200028020020002802046a20013a00002000200028020441016a3602040b6001027f20011054220241b7016a22034180024e044010000b2000200341ff017110d2012000200028020420026a10d101200028020420002802006a417f6a2100034020010440200020013a0000200141087621012000417f6a21000c010b0b0b0bfa0301004180080bf203746f70696331006461746131006a735f636f6e7472616374006576656e740073657455696e7433324576740073657455696e743136457674007472616e7366657200696e69740073657455696e74380067657455696e74380073657455696e7431360067657455696e7431360073657455696e7433320067657455696e7433320073657455696e7436340067657455696e74363400736574537472696e6700676574537472696e6700736574426f6f6c00676574426f6f6c00736574436861720067657443686172007365744d657373616765006765744d657373616765007365744d794d657373616765006765744d794d65737361676500736574496e743800676574496e743800736574496e74313600676574496e74313600736574496e74333200676574496e74333200736574496e74363400676574496e74363400736574566563746f7200676574566563746f72007365744d6170006765744d617000746573744d756c7469506172616d730073657442797465730067657442797465730073657441727261790067657441727261790073657450616972006765745061697200736574536574006765745365740073657446697865644861736800676574466978656448617368007365744c697374006765744c69737400736574416464726573730067657441646472657373' +cabi = [{"constant":false,"input":[{"name":"input","type":"string[10]"}],"name":"setArray","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getUint32","output":"uint32","type":"Action"},{"constant":false,"input":[{"name":"input","type":"int64"}],"name":"setInt64","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getInt64","output":"int64","type":"Action"},{"constant":false,"input":[{"name":"input","type":"pair"}],"name":"setPair","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getPair","output":"pair","type":"Action"},{"anonymous":false,"input":[{"name":"topic","type":"string"},{"name":"arg1","type":"string"}],"name":"transfer","topic":1,"type":"Event"},{"anonymous":false,"input":[{"name":"topic","type":"string"},{"name":"arg1","type":"string"},{"name":"arg2","type":"uint16"}],"name":"setUint16Evt","topic":1,"type":"Event"},{"constant":false,"input":[{"name":"addr","type":"FixedHash<20>"}],"name":"setAddress","output":"void","type":"Action"},{"anonymous":false,"input":[{"name":"topic1","type":"string"},{"name":"topic2","type":"uint32"},{"name":"arg1","type":"string"},{"name":"arg2","type":"uint32"},{"name":"arg3","type":"uint32"}],"name":"setUint32Evt","topic":2,"type":"Event"},{"constant":false,"input":[],"name":"init","output":"void","type":"Action"},{"constant":false,"input":[{"name":"input","type":"uint8"}],"name":"setUint8","output":"void","type":"Action"},{"baseclass":[],"fields":[{"name":"head","type":"string"}],"name":"message","type":"struct"},{"constant":false,"input":[{"name":"msg","type":"message"}],"name":"setMessage","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getUint8","output":"uint8","type":"Action"},{"constant":false,"input":[{"name":"input","type":"uint16"}],"name":"setUint16","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getUint16","output":"uint16","type":"Action"},{"constant":false,"input":[{"name":"input","type":"uint32"}],"name":"setUint32","output":"void","type":"Action"},{"constant":false,"input":[{"name":"input","type":"uint64"}],"name":"setUint64","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getUint64","output":"uint64","type":"Action"},{"constant":false,"input":[{"name":"input","type":"string"}],"name":"setString","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getString","output":"string","type":"Action"},{"constant":false,"input":[{"name":"input","type":"bool"}],"name":"setBool","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getBool","output":"bool","type":"Action"},{"constant":false,"input":[{"name":"input","type":"int8"}],"name":"setChar","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getChar","output":"int8","type":"Action"},{"constant":true,"input":[],"name":"getMessage","output":"message","type":"Action"},{"baseclass":["message"],"fields":[{"name":"body","type":"string"},{"name":"end","type":"string"}],"name":"my_message","type":"struct"},{"constant":false,"input":[{"name":"msg","type":"my_message"}],"name":"setMyMessage","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getMyMessage","output":"my_message","type":"Action"},{"constant":false,"input":[{"name":"input","type":"int8"}],"name":"setInt8","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getSet","output":"set","type":"Action"},{"constant":true,"input":[],"name":"getInt8","output":"int8","type":"Action"},{"constant":false,"input":[{"name":"input","type":"int16"}],"name":"setInt16","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getInt16","output":"int16","type":"Action"},{"constant":false,"input":[{"name":"input","type":"int32"}],"name":"setInt32","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getInt32","output":"int32","type":"Action"},{"constant":false,"input":[{"name":"vec","type":"uint16[]"}],"name":"setVector","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getVector","output":"uint16[]","type":"Action"},{"constant":false,"input":[{"name":"input","type":"map"}],"name":"setMap","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getMap","output":"map","type":"Action"},{"constant":false,"input":[{"name":"msg","type":"message"},{"name":"input1","type":"int32"},{"name":"input2","type":"bool"}],"name":"testMultiParams","output":"void","type":"Action"},{"constant":false,"input":[{"name":"input","type":"uint8[]"}],"name":"setBytes","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getBytes","output":"uint8[]","type":"Action"},{"constant":true,"input":[],"name":"getArray","output":"string[10]","type":"Action"},{"constant":false,"input":[{"name":"input","type":"set"}],"name":"setSet","output":"void","type":"Action"},{"constant":false,"input":[{"name":"input","type":"FixedHash<256>"}],"name":"setFixedHash","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getFixedHash","output":"FixedHash<256>","type":"Action"},{"constant":false,"input":[{"name":"input","type":"list"}],"name":"setList","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getList","output":"list","type":"Action"},{"constant":true,"input":[],"name":"getAddress","output":"FixedHash<20>","type":"Action"}] + +# Instantiate and deploy contract +Payable = platon.wasmcontract(abi=cabi, bytecode=bytecode,vmtype=1) + +tx_hash = Payable.constructor().transact( + { + 'from':from_address, + 'gas':1500000, + } +) + +# Wait for the transaction to be mined, and get the transaction receipt +tx_receipt = platon.waitForTransactionReceipt(tx_hash) +print(tx_receipt) + + +# Create the contract instance with the newly-deployed address +payable = platon.wasmcontract(address=tx_receipt.contractAddress, abi=cabi,vmtype=1) + +# tx_hash0 = payable.functions.setBool(false).transact( +# { +# 'from':from_address, +# 'gas':1500000, +# } +# ) +# tx_hash1 = payable.functions.setInt64(-9223372036854775808).transact( +# { +# 'from':from_address, +# 'gas':1500000, +# } +# ) +# +# tx_hash2 = payable.functions.setUint64(18446744073709551615).transact( +# { +# 'from':from_address, +# 'gas':1500000, +# } +# ) + +# tx_hash3 = payable.functions.setInt32(-2147483648).transact( +# { +# 'from':from_address, +# 'gas':1500000, +# } +# ) +# +# tx_hash4 = payable.functions.setUint32(4294967295).transact( +# { +# 'from':from_address, +# 'gas':1500000, +# } +# ) +# tx_hash5 = payable.functions.setString('helloworld').transact( +# { +# 'from':from_address, +# 'gas':1500000, +# } +# ) +# tx_hash6 = payable.functions.setChar(62).transact( +# { +# 'from':from_address, +# 'gas':1500000, +# } +# ) +# tx_hash7 = payable.functions.setAddress('lax1du4w3q0h5gpxh2vpdvtl7m8h2p9qj40a2krhx7').transact( +# { +# 'from':from_address, +# 'gas':1500000, +# } +# ) +# liststring=['hello','this way','go home'] +# tx_hash8 = payable.functions.setList(liststring).transact( +# { +# 'from':from_address, +# 'gas':1500000, +# } +# ) +# uintbyte=['0x23','0xd1','0xf3'] +# tx_hash9 = payable.functions.setBytes(uintbyte).transact( +# { +# 'from':from_address, +# 'gas':1500000, +# } +# ) +# mapstr=[['hello world','may the force with you'],['how are you','fine,thanks and you ?']] +# tx_hash10 = payable.functions.setMap(mapstr).transact( +# { +# 'from':from_address, +# 'gas':1500000, +# } +# ) +# arraystr=['hello','world','may', 'the', 'force', 'with', 'you','impossible','dancing', 'in dark'] +# tx_hash11 = payable.functions.setArray(arraystr).transact( +# { +# 'from':from_address, +# 'gas':1500000, +# } +# ) +# pairlist=['hello',-123] +# tx_hash12 = payable.functions.setPair(pairlist).transact( +# { +# 'from':from_address, +# 'gas':1500000, +# } +# ) +# mymessage=[['HelloWorld'], 'Wasm', 'Good'] +# tx_hash13 = payable.functions.setMyMessage(mymessage).transact( +# { +# 'from':from_address, +# 'gas':1500000, +# } +# ) +# message=['HelloWorld'] +# tx_hash14 = payable.functions.setMessage(message).transact( +# { +# 'from':from_address, +# 'gas':1500000, +# } +# ) +# Wait for the transaction to be mined, and get the transaction receipt +# tx_receipt = platon.waitForTransactionReceipt(tx_hash1) +# print(platon.waitForTransactionReceipt(tx_hash0)) +# print(platon.waitForTransactionReceipt(tx_hash1)) +# print(platon.waitForTransactionReceipt(tx_hash2)) +# print(platon.waitForTransactionReceipt(tx_hash3)) +# print(platon.waitForTransactionReceipt(tx_hash4)) +# print(platon.waitForTransactionReceipt(tx_hash5)) +# print(platon.waitForTransactionReceipt(tx_hash6)) +# print(platon.waitForTransactionReceipt(tx_hash7)) +# print(platon.waitForTransactionReceipt(tx_hash8)) +# print(platon.waitForTransactionReceipt(tx_hash9)) +# print(platon.waitForTransactionReceipt(tx_hash10)) +# print(platon.waitForTransactionReceipt(tx_hash11)) +# print(platon.waitForTransactionReceipt(tx_hash12)) +# print(platon.waitForTransactionReceipt(tx_hash13)) + +# print(platon.waitForTransactionReceipt(tx_hash14)) +# hrpgot, data = bech32.decode("lax", from_address) +# address = to_checksum_address(bytes(data)) +# print(address) +# # Display the default greeting from the contract +# print('get : {}'.format( +# payable.functions.getBool().call() +# )) +# get : True +# get : False +# print('get : {}'.format( +# payable.functions.getInt64().call() +# )) +# # get : -9223372036854775808 +# print('get : {}'.format( +# payable.functions.getUint64().call() +# )) +# # get : 18446744073709551615 +# print('get : {}'.format( +# payable.functions.getInt32().call() +# )) +# # get : -2147483648 +# print('get : {}'.format( +# payable.functions.getUint32().call() +# )) +# # get : 4294967295 +# print('get : {}'.format( +# payable.functions.getString().call() +# )) +# get : helloworld +# print('get : {}'.format( +# payable.functions.getChar().call() +# )) +# get : 62 +# print('get : {}'.format( +# payable.functions.getAddress().call() +# )) +# get : lax1du4w3q0h5gpxh2vpdvtl7m8h2p9qj40a2krhx7 +# print('get : {}'.format( +# payable.functions.getList().call() +# )) +# get : ['hello', 'this way', 'go home'] +# print('get : {}'.format( +# payable.functions.getBytes().call() +# )) +# get : ['0x23', '0xd1', '0xf3'] +# print('get : {}'.format( +# payable.functions.getMap().call() +# )) +# get : [['hello world', 'may the force with you'], ['how are you', 'fine,thanks and you ?']] +# print('get : {}'.format( +# payable.functions.getArray().call() +# )) +# get : ['hello', 'world', 'may', 'the', 'force', 'with', 'you', 'impossible', 'dancing', 'in dark'] +# print('get : {}'.format( +# payable.functions.getPair().call() +# )) +# get : ['hello', 133] +# print('get : {}'.format( +# payable.functions.getMyMessage().call() +# )) +# get : [['HelloWorld'], 'Wasm', 'Good'] +# print('get : {}'.format( +# payable.functions.getMessage().call() +# )) +# get : ['HelloWorld'] \ No newline at end of file diff --git a/tests/WasmTest1.py b/tests/WasmTest1.py new file mode 100644 index 0000000..d71c65d --- /dev/null +++ b/tests/WasmTest1.py @@ -0,0 +1,74 @@ +from hexbytes import HexBytes +from client_sdk_python import Web3, HTTPProvider +from client_sdk_python.eth import PlatON +# import binascii +# f = open('D:/juzhen/SimpleStorage.wasm','rb') +# contents=f.read() +# bytecode=binascii.b2a_hex(contents) + +true = True +false = False +#10.1.1.5 ./keytool genkeypair +# Address: lax1du4w3q0h5gpxh2vpdvtl7m8h2p9qj40a2krhx7 +# PrivateKey: de66562d36f1db46a55f966cfb0eb0981e3e219aa6050612e9f3cb29b8b5c89d +# PublicKey : 6c71c6cfaed8732dafe6ce8888165ac6c8a126e286c226d0ea08fcac768ece512d1eeffad2c442ade2376b2c47472dcea7e30882855f5a3557261b95a72ae9d8 + +# 10.1.1.8 juzix@juzix:~/linux/bin$ ./keytool genkeypair +# Address: lax13gz7uf8eht4p0leeq3r5z6c88es458twj2tfu9 +# PrivateKey: a90f9b646e699909cc5a5c8a95bff1bfd744755fa99a0db03327212527d3c33b +# PublicKey : fc731c6429a0b752e896aa9593afdbae9c10f5f7b77fbcb28820aa9600c2273cf2291deca15670432feac9dbdd56097772bc4cb8d219d094055107e004da6e3d + + +w3 = Web3(HTTPProvider("http://10.1.1.2:6789")) +platon = PlatON(w3) +print(w3.isConnected()) +# from_address = "lax1du4w3q0h5gpxh2vpdvtl7m8h2p9qj40a2krhx7" +from_address = "lax1uqug0zq7rcxddndleq4ux2ft3tv6dqljphydrl" +print(from_address) + +# send_privatekey = "de66562d36f1db46a55f966cfb0eb0981e3e219aa6050612e9f3cb29b8b5c89d" +send_privatekey = "983759fe9aac227c535b21d78792d79c2f399b1d43db46ae6d50a33875301557" + + +# bytecode='0061736d0100000001480d60027f7f0060017f017f60017f0060027f7f017f60037f7f7f017f60000060037f7f7f0060047f7f7f7f017f60047f7f7f7f0060027f7e006000017f60027f7e017f60017f017e02a9010703656e760c706c61746f6e5f70616e6963000503656e7617706c61746f6e5f6765745f696e7075745f6c656e677468000a03656e7610706c61746f6e5f6765745f696e707574000203656e7617706c61746f6e5f6765745f73746174655f6c656e677468000303656e7610706c61746f6e5f6765745f7374617465000703656e7610706c61746f6e5f7365745f7374617465000803656e760d706c61746f6e5f72657475726e0000034e4d05000003030307000201000201050104060201000c000101010902000b0203030507010201000003090404060002000104000003000403020000080001000407020406020000050601010800000405017001030305030100020608017f0141d088040b073904066d656d6f72790200115f5f7761736d5f63616c6c5f63746f727300070f5f5f66756e63735f6f6e5f65786974002706696e766f6b6500140908010041010b0208080ac9644d0400104d0b0b00200041186a200110090b800101027f230041206b22032400024020002802042202200028020847044020022001100b1a2000200028020441246a3602040c010b200341086a2000200220002802006b41246d220241016a100c2002200041086a100d22022802082001100b1a2002200228020841246a36020820002002100e2002100f0b200341206a24000ba10101037f20004200370200200041086a2202410036020020012d0000410171450440200020012902003702002002200141086a28020036020020000f0b20012802082103024020012802042201410a4d0440200020014101743a0000200041016a21020c010b200141106a4170712204101321022000200136020420002004410172360200200020023602080b200220032001104e200120026a41003a000020000b250020002001100a1a2000410c6a2001410c6a100a1a200041186a200141186a100a1a20000b2f01017f2001200028020820002802006b41246d2200410174220220022001491b41c7e3f138200041e3f1b81c491b0b4c01017f2000410036020c200041106a2003360200200104402001101021040b2000200436020020002004200241246c6a220236020820002004200141246c6a36020c2000200236020420000b900101027f2000280204210220002802002103034020022003464504402001280204415c6a2002415c6a2202101120012001280204415c6a3602040c010b0b200028020021022000200128020436020020012002360204200028020421022000200128020836020420012002360208200028020821022000200128020c3602082001200236020c200120012802043602000b2b01027f200028020821012000280204210203402001200247044020002001415c6a22013602080c010b0b0b0900200041246c10130b620020002001290200370200200041086a200141086a28020036020020011012200041146a200141146a2802003602002000200129020c37020c2001410c6a1012200041206a200141206a28020036020020002001290218370218200141186a10120b2201017f03402001410c470440200020016a4100360200200141046a21010c010b0b0b0b002000410120001b10150b9f0602057f017e230041a0016b22002400104d10012201101522031002200041206a200041086a200320011016220241001017200041206a101802400240200041206a1019450d002000280224450d0020002802202d000041c001490d010b10000b20004180016a200041206a101a200028028401220141094f044010000b20002802800121030340200104402001417f6a210120033100002005420886842105200341016a21030c010b0b024002402005500d00418008101b200551044020024101101c0c020b418508101b200551044020024102101c0c020b419108101b20055104402002101d410147044010000b200041206a101e21032000413c6a280200210220002802382104200041d8006a101f210120004198016a410036020020004190016a420037030020004188016a4200370300200042003703800120004180016a200220046b41246d41ff0171ad22051020200028028001210220004180016a4104721021200120021022200120051023220128020c200141106a28020047044010000b200128020020012802041006200128020c22020440200120023602100b200310240c020b41a208101b2005520d002002101d410247044010000b200041206a200241011017200041206a101802400240200041206a1019450d002000280224450d0020002802202d000041c001490d010b10000b20004180016a200041206a101a200028028401220141024f044010000b4100210220002802800121030340200104402001417f6a210120032d00002102200341016a21030c010b0b200041206a101e2103200041c8006a200041206a280218200241ff017141246c6a410c6a100a1a200041d8006a101f210120004198016a410036020020004190016a420037030020004188016a4200370300200042003703800120004180016a200041f0006a200041c8006a100a102521022000280280012104200241046a1021200120041022200120004180016a200041c8006a100a1026220128020c200141106a28020047044010000b200128020020012802041006200128020c22020440200120023602100b200310240c010b10000b1027200041a0016a24000b9b0101047f230041106b220124002001200036020c2000047f41c808200041086a2202411076220041c8082802006a220336020041c40841c408280200220420026a41076a417871220236020002400240200341107420024d044041c808200341016a360200200041016a21000c010b2000450d010b200040000d0010000b20042001410c6a4104103c41086a0541000b2100200141106a240020000b0c00200020012002411c10280bc90202067f017e230041106b220324002001280208220520024b0440200341086a2001102d20012003280208200328020c102e36020c20032001102d410021052001027f410020032802002207450d001a410020032802042208200128020c2206490d001a200820062006417f461b210420070b360210200141146a2004360200200141003602080b200141106a210603402001280214210402402005200249044020040d01410021040b200020062802002004411410281a200341106a24000f0b20032001102d41002104027f410020032802002205450d001a410020032802042208200128020c2207490d001a200820076b2104200520076a0b2105200120043602142001200536021020032006410020052004102e10512001200329030022093702102001200128020c2009422088a76a36020c2001200128020841016a22053602080c000b000b4101017f200028020445044010000b0240200028020022012d0000418101470d00200028020441014d047f100020002802000520010b2c00014100480d0010000b0b980101037f200028020445044041000f0b20001018200028020022022c0000220141004e044020014100470f0b027f4101200141807f460d001a200141ff0171220341b7014d0440200028020441014d047f100020002802000520020b2d00014100470f0b4100200341bf014b0d001a2000280204200141ff017141ca7e6a22014d047f100020002802000520020b20016a2d00004100470b0bd50101047f200110292204200128020422024b04401000200128020421020b200128020021052000027f02400240200204404100210120052c00002203417f4a0d01027f200341ff0171220141bf014d04404100200341ff017141b801490d011a200141c97e6a0c010b4100200341ff017141f801490d001a200141897e6a0b41016a21010c010b4101210120050d000c010b41002103200120046a20024b0d0020022001490d00410020022004490d011a200120056a2103200220016b20042004417f461b0c010b41000b360204200020033602000b3901027e42a5c688a1c89ca7f94b210103402000300000220250450440200041016a2100200142b383808080207e20028521010c010b0b20010b6701027f23004180016b22022400200241306a102a200241306a102b21032000101d410247044010000b200241086a200041011017200241086a2003102c200241086a101e2100200241086a200241d8006a2003100b20011100002000102420024180016a24000b800101047f230041106b2201240002402000280204450d0020002802002d000041c001490d00200141086a2000102d200128020c210003402000450d01200141002001280208220320032000102e22046a20034520002004497222031b3602084100200020046b20031b2100200241016a21020c000b000b200141106a240020020be906010c7f230041b0016b22042400200042003702182000428ed1dd82cbd38f9ca07f3703102000410036020820004200370200200041206a4100360200200441206a101f22072000290310102f200728020c200741106a28020047044010000b200041186a21052000411c6a21090240200728020022022007280204220810032206450d002006101321030340200120036a41003a00002006200141016a2201470d000b20022008200320011004417f460440410021010c010b02400240200441086a200341016a200120036a2003417f736a10162203280204450d0020032802002d000041c001490d002003101d21012000280220200028021822026b41246d20014904402005200441386a2001200028021c20026b41246d200041206a100d2201100e2001100f0b20044188016a2003410110302101200441f8006a2003410010302108200041206a210b20012802042103034020082802042003464100200128020822022008280208461b0d02200441e0006a20032002411c1028200441386a102b2203102c0240200028021c220220002802204904402002200310112009200928020041246a3602000c010b20044198016a2005200220052802006b41246d220241016a100c2002200b100d210220042802a00120031011200420042802a00141246a3602a00120052002100e2002100f0b20012001280204220320012802086a410020031b22033602042001280200220204402001200236020820032002102e210a2001027f2001280204220c4504404100210241000c010b41002102410020012802082203200a490d001a2003200a200a417f461b2102200c0b2203ad2002ad42208684370204200141002001280200220a20026b22022002200a4b1b3602000c0105200141003602080c010b000b000b10000b200621010b200728020c22030440200720033602100b024020010d0020002802042206200028020022036b41246d22022000280220200028021822016b41246d4d04402002200928020020016b41246d22084b044020032003200841246c6a2202200110311a20022006200910320c020b2005200320062001103110330c010b200104402005103420004100360220200042003702180b200020052002100c2202101022013602182000200136021c20002001200241246c6a36022020032006200910320b200441b0016a240020000b29002000410036020820004200370200200041001035200041146a41003602002000420037020c20000b840102027f017e4101210320014280015a0440034020012004845045044020044238862001420888842101200241016a2102200442088821040c010b0b200241384f047f2002103620026a0520020b41016a21030b200041186a28020022020440200041086a280200200041146a2802002002103721000b2000200028020020036a3602000bea0101047f230041106b22042400200028020422012000280210220241087641fcffff07716a2103027f410020012000280208460d001a2003280200200241ff07714102746a0b2101200441086a20001038200428020c210203400240200120024604402000410036021420002802082103200028020421010340200320016b41027522024103490d022000200141046a22013602040c000b000b200141046a220120032802006b418020470d0120032802042101200341046a21030c010b0b2002417f6a220241014d04402000418004418008200241016b1b3602100b200020011039200441106a24000b1300200028020820014904402000200110350b0bbc0202037f037e024020015004402000418001103f0c010b20014280015a044020012107034020062007845045044020064238862007420888842107200241016a2102200642088821060c010b0b0240200241384f04402002210303402003044020034108762103200441016a21040c010b0b200441c9004f044010000b2000200441b77f6a41ff0171103f2000200028020420046a1053200028020420002802006a417f6a21042002210303402003450d02200420033a0000200341087621032004417f6a21040c000b000b200020024180017341ff0171103f0b2000200028020420026a1053200028020420002802006a417f6a210203402001200584500d02200220013c0000200542388620014208888421012002417f6a2102200542088821050c000b000b20002001a741ff0171103f0b20004101104220000be206010d7f230041b0016b22012400200141186a101f2106200141a8016a22024100360200200141a0016a2205420037030020014198016a22044200370300200142003703900120014190016a20002903101020200128029001210720014190016a410472102120062007102220062000290310102f200628020c200641106a28020047044010000b200628020421092006280200210a2001101f21032002410036020020054200370300200442003703002001420037039001027f20002802182000411c6a280200460440200141013602900141010c010b20014190016a4100103a2107200028021c200028021822026b2105037f2005047f20074100103a22042002103b2004200141d0006a2002410c6a100a102520014180016a200241186a100a10254101103a1a2005415c6a2105200241246a21020c010520074101103a1a2001280290010b0b0b210420014190016a410472102141011013220241fe013a0000200328020c200341106a28020047044010000b200241016a21072003280204220541016a220820032802084b047f20032008103520032802040520050b20032802006a20024101103c1a2003200328020441016a3602042003200420026b20076a10222003200028021c20002802186b41246d103d210b200028021c200028021822026b2105200141d0006a410472210c20014190016a410472210d034020050440200b4103103d210420014100360268200142003703602001420037035820014200370350200141d0006a2002103b200141d0006a200141406b2002410c6a2207100a1025200141306a200241186a2208100a10251a20042001280250102220044101103d2104200141003602a801200142003703a0012001420037039801200142003703900120014190016a20014180016a2002100a10251a200420012802900110222004200141f0006a2002100a10262104200d1021200420014190016a2007100a102620014180016a2008100a10261a200c10212005415c6a2105200241246a21020c010b0b0240200328020c2003280210460440200328020021020c010b100020032802002102200328020c2003280210460d0010000b200a2009200220032802041005200328020c22020440200320023602100b200628020c22020440200620023602100b200041186a103e2000103e200141b0016a24000ba10101037f41012103024002400240200128020420012d00002202410176200241017122041b220241014d0440200241016b0d032001280208200141016a20041b2c0000417f4c0d010c030b200241374b0d010b200241016a21030c010b2002103620026a41016a21030b027f200041186a28020022010440200041086a280200200041146a280200200110370c010b20000b2201200128020020036a36020020000b910101047f410121022001280208200141016a20012d0000220441017122051b210302400240024002402001280204200441017620051b2201410146044020032c000022014100480d012000200141ff0171103f0c040b200141374b0d01200121020b200020024180017341ff0171103f0c010b200020011040200121020b200020032002410010410b20004101104220000b880101037f41b408410136020041b8082802002100034020000440034041bc0841bc082802002201417f6a2202360200200141014845044041b4084100360200200020024102746a22004184016a280200200041046a28020011020041b408410136020041b80828020021000c010b0b41bc08412036020041b808200028020022003602000c010b0b0b730020004200370210200042ffffffff0f370208200020023602042000200136020002402003410871450d002000104f20024f0d002003410471044010000c010b200042003702000b02402003411071450d002000104f20024d0d0020034104710440100020000f0b200042003702000b20000bff0201037f200028020445044041000f0b2000101841012102024020002802002c00002201417f4a0d00200141ff0171220341b7014d0440200341807f6a0f0b02400240200141ff0171220141bf014d0440024020002802042201200341c97e6a22024d047f100020002802040520010b4102490d0020002802002d00010d0010000b200241054f044010000b20002802002d000145044010000b4100210241b7012101034020012003460440200241384f0d030c0405200028020020016a41ca7e6a2d00002002410874722102200141016a21010c010b000b000b200141f7014d0440200341c07e6a0f0b024020002802042201200341897e6a22024d047f100020002802040520010b4102490d0020002802002d00010d0010000b200241054f044010000b20002802002d000145044010000b4100210241f701210103402001200346044020024138490d0305200028020020016a418a7e6a2d00002002410874722102200141016a21010c010b0b0b200241ff7d490d010b10000b20020bc50201027f200041003a0000200041246a2202417f6a41003a0000200041003a0002200041003a00012002417d6a41003a00002002417e6a41003a0000200041003a00032002417c6a41003a00002000410020006b41037122016a220241003602002002412420016b417c7122016a2200417c6a4100360200024020014109490d002002410036020820024100360204200041786a4100360200200041746a410036020020014119490d002002410036021820024100360214200241003602102002410036020c200041706a41003602002000416c6a4100360200200041686a4100360200200041646a41003602002001200241047141187222016b2100200120026a2101034020004120490d0120014200370300200141186a4200370300200141106a4200370300200141086a4200370300200141206a2101200041606a21000c000b000b0b16002000104a2000410c6a104a200041186a104a20000b5e01017f230041306b220224002002200041001017200241186a200241001017200241186a2001104b200241186a200041011017200241186a2001410c6a104b200241186a200041021017200241186a200141186a104b200241306a24000b2101017f20011029220220012802044b044010000b2000200120011050200210510b2701017f230041206b22022400200241086a2000200141141028104f2100200241206a240020000b09002000200110231a0be70101037f230041106b2204240020004200370200200041086a410036020020012802042103024002402002450440200321020c010b410021022003450d002003210220012802002d000041c001490d00200441086a2001102d20004100200428020c2201200428020822022001102e22032003417f461b20024520012003497222031b220536020820004100200220031b3602042000200120056b3602000c010b20012802002103200128020421012000410036020020004100200220016b20034520022001497222021b36020820004100200120036a20021b3602040b200441106a240020000b3e000340200020014645044020022000104c2002410c6a2000410c6a104c200241186a200041186a104c200241246a2102200041246a21000c010b0b20020b2e000340200020014645044020022802002000100b1a2002200228020041246a360200200041246a21000c010b0b0b0900200020013602040b0b002000200028020010330b2f01017f200028020820014904402001101520002802002000280204103c210220002001360208200020023602000b0b1e01017f03402000044020004108762100200141016a21010c010b0b20010b25002000200120026a417f6a220241087641fcffff07716a280200200241ff07714102746a0b4f01037f20012802042203200128021020012802146a220441087641fcffff07716a21022000027f410020032001280208460d001a2002280200200441ff07714102746a0b360204200020023602000b2501017f200028020821020340200120024645044020002002417c6a22023602080c010b0b0bc30c02077f027e230041306b22042400200041046a2107027f20014101460440200041086a280200200041146a280200200041186a220228020022031037280200210120022003417f6a360200200710434180104f044020072000410c6a280200417c6a10390b200141384f047f2001103620016a0520010b41016a2102200041186a28020022010440200041086a280200200041146a280200200110370c020b20000c010b0240200710430d00200041146a28020022014180084f0440200020014180786a360214200041086a2201280200220228020021032001200241046a360200200420033602182007200441186a10440c010b2000410c6a2802002202200041086a2802006b4102752203200041106a2205280200220620002802046b220141027549044041802010132105200220064704400240200028020c220120002802102202470d0020002802082203200028020422064b04402000200320012003200320066b41027541016a417e6d41027422026a1045220136020c2000200028020820026a3602080c010b200441186a200220066b2201410175410120011b22012001410276200041106a10462102200028020c210320002802082101034020012003470440200228020820012802003602002002200228020841046a360208200141046a21010c010b0b200029020421092000200229020037020420022009370200200029020c21092000200229020837020c2002200937020820021047200028020c21010b200120053602002000200028020c41046a36020c0c020b02402000280208220120002802042202470d00200028020c2203200028021022064904402000200120032003200620036b41027541016a41026d41027422026a104822013602082000200028020c20026a36020c0c010b200441186a200620026b2201410175410120011b2201200141036a410276200041106a10462102200028020c210320002802082101034020012003470440200228020820012802003602002002200228020841046a360208200141046a21010c010b0b200029020421092000200229020037020420022009370200200029020c21092000200229020837020c2002200937020820021047200028020821010b2001417c6a2005360200200020002802082201417c6a22023602082002280200210220002001360208200420023602182007200441186a10440c010b20042001410175410120011b200320051046210241802010132106024020022802082201200228020c2203470d0020022802042205200228020022084b04402002200520012005200520086b41027541016a417e6d41027422036a104522013602082002200228020420036a3602040c010b200441186a200320086b2201410175410120011b22012001410276200241106a280200104621032002280208210520022802042101034020012005470440200328020820012802003602002003200328020841046a360208200141046a21010c010b0b20022902002109200220032902003702002003200937020020022902082109200220032902083702082003200937020820031047200228020821010b200120063602002002200228020841046a360208200028020c2105034020002802082005460440200028020421012000200228020036020420022001360200200228020421012002200536020420002001360208200029020c21092000200229020837020c2002200937020820021047052005417c6a210502402002280204220120022802002203470d0020022802082206200228020c22084904402002200120062006200820066b41027541016a41026d41027422036a104822013602042002200228020820036a3602080c010b200441186a200820036b2201410175410120011b2201200141036a4102762002280210104621062002280208210320022802042101034020012003470440200428022020012802003602002004200428022041046a360220200141046a21010c010b0b20022902002109200220042903183702002002290208210a20022004290320370208200420093703182004200a37032020061047200228020421010b2001417c6a200528020036020020022002280204417c6a3602040c010b0b0b200441186a20071038200428021c410036020041012102200041186a0b2201200128020020026a360200200441306a240020000b2701017f230041106b2202240020004100103a20022001100a10254101103a1a200241106a24000bfc0801067f03400240200020046a2105200120046a210320022004460d002003410371450d00200520032d00003a0000200441016a21040c010b0b200220046b210602402005410371220745044003402006411049450440200020046a2203200120046a2205290200370200200341086a200541086a290200370200200441106a2104200641706a21060c010b0b027f2006410871450440200120046a2103200020046a0c010b200020046a2205200120046a2204290200370200200441086a2103200541086a0b21042006410471044020042003280200360200200341046a2103200441046a21040b20064102710440200420032f00003b0000200341026a2103200441026a21040b2006410171450d01200420032d00003a000020000f0b024020064120490d002007417f6a220741024b0d00024002400240024002400240200741016b0e020102000b2005200120046a220328020022073a0000200541016a200341016a2f00003b0000200041036a2108200220046b417d6a2106034020064111490d03200420086a2203200120046a220541046a2802002202410874200741187672360200200341046a200541086a2802002207410874200241187672360200200341086a2005410c6a28020022024108742007411876723602002003410c6a200541106a2802002207410874200241187672360200200441106a2104200641706a21060c000b000b2005200120046a220328020022073a0000200541016a200341016a2d00003a0000200041026a2108200220046b417e6a2106034020064112490d03200420086a2203200120046a220541046a2802002202411074200741107672360200200341046a200541086a2802002207411074200241107672360200200341086a2005410c6a28020022024110742007411076723602002003410c6a200541106a2802002207411074200241107672360200200441106a2104200641706a21060c000b000b2005200120046a28020022073a0000200041016a21082004417f7320026a2106034020064113490d03200420086a2203200120046a220541046a2802002202411874200741087672360200200341046a200541086a2802002207411874200241087672360200200341086a2005410c6a28020022024118742007410876723602002003410c6a200541106a2802002207411874200241087672360200200441106a2104200641706a21060c000b000b200120046a41036a2103200020046a41036a21050c020b200120046a41026a2103200020046a41026a21050c010b200120046a41016a2103200020046a41016a21050b20064110710440200520032d00003a00002005200328000136000120052003290005370005200520032f000d3b000d200520032d000f3a000f200541106a2105200341106a21030b2006410871044020052003290000370000200541086a2105200341086a21030b2006410471044020052003280000360000200541046a2105200341046a21030b20064102710440200520032f00003b0000200541026a2105200341026a21030b2006410171450d00200520032d00003a00000b20000b8c0201057f2001044020002802042105200041106a2802002202200041146a280200220349044020022001ad2005ad422086843702002000200028021041086a36021020000f0b027f41002002200028020c22046b410375220641016a2202200320046b2203410275220420042002491b41ffffffff01200341037541ffffffff00491b2204450d001a200441037410130b2102200220064103746a22032001ad2005ad4220868437020020032000280210200028020c22066b22016b2105200220044103746a2102200341086a2103200141014e0440200520062001103c1a0b20002002360214200020033602102000200536020c20000f0b200041c001103f2000410041004101104120000b0e0020002802000440200010340b0b2500200041011052200028020020002802046a20013a00002000200028020441016a3602040b5e01027f20011036220241b7016a22034180024e044010000b2000200341ff0171103f2000200028020420026a1053200028020420002802006a417f6a2100034020010440200020013a0000200141087621012000417f6a21000c010b0b0b2d00200020021052200028020020002802046a20012002103c1a2000200028020420026a3602042000200310420b820201047f02402001450d00034020002802102202200028020c460d01200241786a28020020014904401000200028021021020b200241786a2203200328020020016b220136020020010d012000200336021020004101200028020422032002417c6a28020022016b22021036220441016a20024138491b220520036a1053200120002802006a220320056a2003200210490240200241374d0440200028020020016a200241406a3a00000c010b200441f7016a220341ff014d0440200028020020016a20033a00002000280200200120046a6a210103402002450d02200120023a0000200241087621022001417f6a21010c000b000b10000b410121010c000b000b0b2801017f200028020820002802046b2201410874417f6a410020011b200028021420002802106a6b0ba10202057f017e230041206b22052400024020002802082202200028020c2203470d0020002802042204200028020022064b04402000200420022004200420066b41027541016a417e6d41027422036a104522023602082000200028020420036a3602040c010b200541086a200320066b2202410175410120021b220220024102762000410c6a10462103200028020821042000280204210203402002200446450440200328020820022802003602002003200328020841046a360208200241046a21020c010b0b20002902002107200020032902003702002003200737020020002902082107200020032902083702082003200737020820031047200028020821020b200220012802003602002000200028020841046a360208200541206a24000b2501017f200120006b220141027521032001044020022000200110490b200220034102746a0b4f01017f2000410036020c200041106a2003360200200104402001410274101321040b200020043602002000200420024102746a22023602082000200420014102746a36020c2000200236020420000b2b01027f200028020821012000280204210203402001200247044020002001417c6a22013602080c010b0b0b1b00200120006b22010440200220016b22022000200110490b20020b8d0301037f024020002001460d00200120006b20026b410020024101746b4d0440200020012002103c1a0c010b20002001734103712103027f024020002001490440200020030d021a410021030340200120036a2105200020036a2204410371450440200220036b210241002103034020024104490d04200320046a200320056a280200360200200341046a21032002417c6a21020c000b000b20022003460d04200420052d00003a0000200341016a21030c000b000b024020030d002001417f6a21040340200020026a22034103714504402001417c6a21032000417c6a2104034020024104490d03200220046a200220036a2802003602002002417c6a21020c000b000b2002450d042003417f6a200220046a2d00003a00002002417f6a21020c000b000b2001417f6a210103402002450d03200020026a417f6a200120026a2d00003a00002002417f6a21020c000b000b200320056a2101200320046a0b210303402002450d01200320012d00003a00002002417f6a2102200341016a2103200141016a21010c000b000b0b170020004200370200200041086a4100360200200010120bf30201057f230041206b22022400024002402000280204044020002802002d000041c001490d010b200241086a104a0c010b200241186a2000101a2000102921030240024002400240200228021822000440200228021c220520034f0d010b41002100200241106a410036020020024200370308410021050c010b200241106a4100360200200242003703082000200520032003417f461b22046a21052004410a4b0d010b200220044101743a0008200241086a41017221030c010b200441106a4170712206101321032002200436020c20022006410172360208200220033602100b03402000200546450440200320002d00003a0000200341016a2103200041016a21000c010b0b200341003a00000b024020012d0000410171450440200141003b01000c010b200128020841003a00002001410036020420012d0000410171450d00200141003602000b20012002290308370200200141086a200241106a280200360200200241086a1012200241206a24000b8c0201047f20002001470440200128020420012d00002202410176200241017122041b2102200141016a210320012802082105410a21012005200320041b210420002d0000410171220304402000280200417e71417f6a21010b200220014d0440027f2003044020002802080c010b200041016a0b21012002044020012004200210490b200120026a41003a000020002d00004101710440200020023602040f0b200020024101743a00000f0b416f2103200141e6ffffff074d0440410b20014101742201200220022001491b220141106a4170712001410b491b21030b20031013220120042002104e200020023602042000200341017236020020002001360208200120026a41003a00000b0b3501017f230041106b220041d0880436020c41c008200028020c41076a417871220036020041c408200036020041c8083f003602000b100020020440200020012002103c1a0b0b2e01017f200028020445044041000f0b4101210120002802002c0000417f4c047f20001050200010296a0520010b0b5b00027f027f41002000280204450d001a410020002802002c0000417f4a0d011a20002802002d0000220041bf014d04404100200041b801490d011a200041c97e6a0c010b4100200041f801490d001a200041897e6a0b41016a0b0b5b01027f2000027f0240200128020022054504400c010b200220036a200128020422014b0d0020012002490d00410020012003490d011a200220056a2104200120026b20032003417f461b0c010b41000b360204200020043602000b1b00200028020420016a220120002802084b04402000200110350b0b0f00200020011035200020013602040b0b3901004180080b32696e6974006164645f6d657373616765006765745f6d6573736167655f73697a65006765745f6d6573736167655f626f64790a' +# abi=[{"baseclass":[],"fields":[{"name":"head","type":"string"}],"name":"message","type":"struct"},{"baseclass":["message"],"fields":[{"name":"body","type":"string"},{"name":"end","type":"string"}],"name":"my_message","type":"struct"},{"constant":false,"input":[{"name":"one_message","type":"my_message"}],"name":"init","output":"void","type":"Action"},{"constant":false,"input":[{"name":"one_message","type":"my_message"}],"name":"add_message","output":"void","type":"Action"},{"constant":true,"input":[],"name":"get_message_size","output":"uint8","type":"Action"},{"constant":true,"input":[{"name":"index","type":"uint8"}],"name":"get_message_body","output":"string","type":"Action"}] +bytecode='0061736d0100000001470d60017f017f60027f7f0060000060017f0060037f7f7f0060047f7f7f7f0060027f7f017f60037f7f7f017f60047f7f7f7f017f60017f017e60027f7e006000017f60017e017f02a9010703656e760c706c61746f6e5f70616e6963000203656e7617706c61746f6e5f6765745f696e7075745f6c656e677468000b03656e7610706c61746f6e5f6765745f696e707574000303656e7617706c61746f6e5f6765745f73746174655f6c656e677468000603656e7610706c61746f6e5f6765745f7374617465000803656e7610706c61746f6e5f7365745f7374617465000503656e760d706c61746f6e5f72657475726e000103201f0202000704090903000300000c010a020803000001070106010104020000050405017001010105030100020608017f0141b088040b073904066d656d6f72790200115f5f7761736d5f63616c6c5f63746f727300070f5f5f66756e63735f6f6e5f65786974001606696e766f6b6500080ad02a1f040010220b940202047f017e230041d0006b22012400102210012200100922021002200141386a200141086a20022000100a22004100100b02400240200141386a100c2204500d00418008100d20045104402000100e200141386a100f10100c020b418508100d200451044020001011410247044010000b200141386a20004101100b200141386a100c2104200141386a100f210020012004370348200010100c020b418908100d2004520d002000100e200141206a100f210220012903302104200141386a10122200200410131014200020041015200028020c200041106a28020047044010000b200028020020002802041006200028020c22030440200020033602100b200210100c010b10000b1016200141d0006a24000b9b0101047f230041106b220124002001200036020c2000047f41a408200041086a2202411076220041a4082802006a220336020041a00841a008280200220420026a41076a417871220236020002400240200341107420024d044041a408200341016a360200200041016a21000c010b2000450d010b200040000d0010000b20042001410c6a4104101c41086a0541000b2100200141106a240020000b0c00200020012002411c10170bc90202067f017e230041106b220324002001280208220520024b0440200341086a2001101d20012003280208200328020c101e36020c20032001101d410021052001027f410020032802002207450d001a410020032802042208200128020c2206490d001a200820062006417f461b210420070b360210200141146a2004360200200141003602080b200141106a210603402001280214210402402005200249044020040d01410021040b200020062802002004411410171a200341106a24000f0b20032001101d41002104027f410020032802002205450d001a410020032802042208200128020c2207490d001a200820076b2104200520076a0b2105200120043602142001200536021020032006410020052004101e10252001200329030022093702102001200128020c2009422088a76a36020c2001200128020841016a22053602080c000b000bad0302057f017e20001018024002402000280204450d00200010180240200028020022012c0000220241004e044020020d010c020b200241807f460d00200241ff0171220341b7014d0440200028020441014d04401000200028020021010b20012d00010d010c020b200341bf014b0d012000280204200241ff017141ca7e6a22024d04401000200028020021010b200120026a2d0000450d010b2000280204450d0020012d000041c001490d010b10000b200010192204200028020422014b04401000200028020421010b20002802002105024002400240200104404100210320052c00002200417f4a0d01027f200041ff0171220341bf014d04404100200041ff017141b801490d011a200341c97e6a0c010b4100200041ff017141f801490d001a200341897e6a0b41016a21030c010b4101210320050d00410021000c010b41002100200320046a20014b0d0020012004490d004100210220012003490d01200320056a2102200120036b20042004417f461b22004109490d0110000c010b410021020b0340200004402000417f6a210020023100002006420886842106200241016a21020c010b0b20060b3901027e42a5c688a1c89ca7f94b210103402000300000220250450440200041016a2100200142b383808080207e20028521010c010b0b20010b0e0020001011410147044010000b0bda0101077f230041306b22052400200042d1f0fad48ae09ad34537030820004200370300200541186a1012220220002903081015200228020c200241106a28020047044010000b02400240200228020022062002280204220710032204450d002004101a21030340200120036a41003a00002004200141016a2201470d000b20062007200320011004417f460d0020002005200341016a200120036a2003417f736a100a100c3703100c010b410021040b200228020c22010440200220013602100b2004450440200020002903003703100b200541306a240020000bb40201097f230041306b22032400200341186a10122202200029030810131014200220002903081015200228020c200241106a28020047044010000b20022802042105200228020021062003101221012000290310101321074101101a220441fe013a0000200128020c200141106a28020047044010000b2001280204220841016a220920012802084b047f20012009101b20012802040520080b20012802006a20044101101c1a2001200128020441016a3602042001200441016a200720046b6a10142001200029031010150240200128020c2001280210460440200128020021000c010b100020012802002100200128020c2001280210460d0010000b20062005200020012802041005200128020c22000440200120003602100b200228020c22010440200220013602100b200341306a24000b800101047f230041106b2201240002402000280204450d0020002802002d000041c001490d00200141086a2000101d200128020c210003402000450d01200141002001280208220320032000101e22046a20034520002004497222031b3602084100200020046b20031b2100200241016a21020c000b000b200141106a240020020b2900200041003602082000420037020020004100101b200041146a41003602002000420037020c20000b7002027f017e4101210120004280015a047f41002101034020002003845045044020034238862000420888842100200141016a2101200342088821030c010b0b024020014138490d002001210203402002450d01200141016a2101200241087621020c000b000b200141016a0520010b0b13002000280208200149044020002001101b0b0bc10402057f027e024020015004402000418001101f0c010b20014280015a044020012108034020072008845045044020074238862008420888842108200241016a2102200742088821070c010b0b0240200241384f04402002210403402004044020044108762104200341016a21030c010b0b200341c9004f044010000b2000200341b77f6a41ff0171101f2000200028020420036a1020200028020420002802006a417f6a21032002210403402004450d02200320043a0000200441087621042003417f6a21030c000b000b200020024180017341ff0171101f0b2000200028020420026a1020200028020420002802006a417f6a21024200210703402001200784500d02200220013c0000200742388620014208888421012002417f6a2102200742088821070c000b000b20002001a741ff0171101f0b0340024020002802102202200028020c460d00200241786a2802004504401000200028021021020b200241786a22042004280200417f6a220336020020030d002000200436021041002104200028020422062002417c6a28020022056b2203210203402002044020024108762102200441016a21040c010b0b20004101200441016a20034138491b220220066a1020200028020020056a220620026a200620031021200341374d0440200028020020056a200341406a3a00000c020b200441084d0440200028020020056a200441776a3a0000200028020020056a20046a210203402003450d03200220033a0000200341087621032002417f6a21020c000b000510000c020b000b0b0b880101037f4190084101360200419408280200210003402000044003404198084198082802002201417f6a220236020020014101484504404190084100360200200020024102746a22004184016a280200200041046a280200110300419008410136020041940828020021000c010b0b4198084120360200419408200028020022003602000c010b0b0b730020004200370210200042ffffffff0f370208200020023602042000200136020002402003410871450d002000102320024f0d002003410471044010000c010b200042003702000b02402003411071450d002000102320024d0d0020034104710440100020000f0b200042003702000b20000b4101017f200028020445044010000b0240200028020022012d0000418101470d00200028020441014d047f100020002802000520010b2c00014100480d0010000b0bff0201037f200028020445044041000f0b2000101841012102024020002802002c00002201417f4a0d00200141ff0171220341b7014d0440200341807f6a0f0b02400240200141ff0171220141bf014d0440024020002802042201200341c97e6a22024d047f100020002802040520010b4102490d0020002802002d00010d0010000b200241054f044010000b20002802002d000145044010000b4100210241b7012101034020012003460440200241384f0d030c0405200028020020016a41ca7e6a2d00002002410874722102200141016a21010c010b000b000b200141f7014d0440200341c07e6a0f0b024020002802042201200341897e6a22024d047f100020002802040520010b4102490d0020002802002d00010d0010000b200241054f044010000b20002802002d000145044010000b4100210241f701210103402001200346044020024138490d0305200028020020016a418a7e6a2d00002002410874722102200141016a21010c010b0b0b200241ff7d490d010b10000b20020b0b002000410120001b10090b2f01017f200028020820014904402001100920002802002000280204101c210220002001360208200020023602000b0bfc0801067f03400240200020046a2105200120046a210320022004460d002003410371450d00200520032d00003a0000200441016a21040c010b0b200220046b210602402005410371220745044003402006411049450440200020046a2203200120046a2205290200370200200341086a200541086a290200370200200441106a2104200641706a21060c010b0b027f2006410871450440200120046a2103200020046a0c010b200020046a2205200120046a2204290200370200200441086a2103200541086a0b21042006410471044020042003280200360200200341046a2103200441046a21040b20064102710440200420032f00003b0000200341026a2103200441026a21040b2006410171450d01200420032d00003a000020000f0b024020064120490d002007417f6a220741024b0d00024002400240024002400240200741016b0e020102000b2005200120046a220328020022073a0000200541016a200341016a2f00003b0000200041036a2108200220046b417d6a2106034020064111490d03200420086a2203200120046a220541046a2802002202410874200741187672360200200341046a200541086a2802002207410874200241187672360200200341086a2005410c6a28020022024108742007411876723602002003410c6a200541106a2802002207410874200241187672360200200441106a2104200641706a21060c000b000b2005200120046a220328020022073a0000200541016a200341016a2d00003a0000200041026a2108200220046b417e6a2106034020064112490d03200420086a2203200120046a220541046a2802002202411074200741107672360200200341046a200541086a2802002207411074200241107672360200200341086a2005410c6a28020022024110742007411076723602002003410c6a200541106a2802002207411074200241107672360200200441106a2104200641706a21060c000b000b2005200120046a28020022073a0000200041016a21082004417f7320026a2106034020064113490d03200420086a2203200120046a220541046a2802002202411874200741087672360200200341046a200541086a2802002207411874200241087672360200200341086a2005410c6a28020022024118742007410876723602002003410c6a200541106a2802002207411874200241087672360200200441106a2104200641706a21060c000b000b200120046a41036a2103200020046a41036a21050c020b200120046a41026a2103200020046a41026a21050c010b200120046a41016a2103200020046a41016a21050b20064110710440200520032d00003a00002005200328000136000120052003290005370005200520032f000d3b000d200520032d000f3a000f200541106a2105200341106a21030b2006410871044020052003290000370000200541086a2105200341086a21030b2006410471044020052003280000360000200541046a2105200341046a21030b20064102710440200520032f00003b0000200541026a2105200341026a21030b2006410171450d00200520032d00003a00000b20000b2101017f20011019220220012802044b044010000b2000200120011024200210250b2701017f230041206b22022400200241086a200020014114101710232100200241206a240020000b3f01027f2000280204220241016a220320002802084b047f20002003101b20002802040520020b20002802006a20013a00002000200028020441016a3602040b0f0020002001101b200020013602040b8d0301037f024020002001460d00200120006b20026b410020024101746b4d0440200020012002101c1a0c010b20002001734103712103027f024020002001490440200020030d021a410021030340200120036a2105200020036a2204410371450440200220036b210241002103034020024104490d04200320046a200320056a280200360200200341046a21032002417c6a21020c000b000b20022003460d04200420052d00003a0000200341016a21030c000b000b024020030d002001417f6a21040340200020026a22034103714504402001417c6a21032000417c6a2104034020024104490d03200220046a200220036a2802003602002002417c6a21020c000b000b2002450d042003417f6a200220046a2d00003a00002002417f6a21020c000b000b2001417f6a210103402002450d03200020026a417f6a200120026a2d00003a00002002417f6a21020c000b000b200320056a2101200320046a0b210303402002450d01200320012d00003a00002002417f6a2102200341016a2103200141016a21010c000b000b0b3501017f230041106b220041b0880436020c419c08200028020c41076a417871220036020041a008200036020041a4083f003602000b2e01017f200028020445044041000f0b4101210120002802002c0000417f4c047f20001024200010196a0520010b0b5b00027f027f41002000280204450d001a410020002802002c0000417f4a0d011a20002802002d0000220041bf014d04404100200041b801490d011a200041c97e6a0c010b4100200041f801490d001a200041897e6a0b41016a0b0b5b01027f2000027f0240200128020022054504400c010b200220036a200128020422014b0d0020012002490d00410020012003490d011a200220056a2104200120026b20032003417f461b0c010b41000b360204200020043602000b0b1301004180080b0c696e69740073657400676574' +abi=[{"constant":false,"input":[{"name":"input","type":"uint64"}],"name":"set","output":"void","type":"Action"},{"constant":false,"input":[],"name":"init","output":"void","type":"Action"},{"constant":true,"input":[],"name":"get","output":"uint64","type":"Action"}] +print(type(abi)) +# Instantiate and deploy contract +Payable = platon.wasmcontract(abi=abi, bytecode=bytecode,vmtype=1) + +tx_hash = Payable.constructor().transact( + { + 'from':from_address, + 'gas':1500000, + } +) + +# Wait for the transaction to be mined, and get the transaction receipt +tx_receipt = platon.waitForTransactionReceipt(tx_hash) +print(tx_receipt) + + +# Create the contract instance with the newly-deployed address +payable = platon.wasmcontract(address=tx_receipt.contractAddress, abi=abi,vmtype=1) + +tx_hash1 = payable.functions.set(10).transact( + { + 'from':from_address, + 'gas':1500000, + } +) + +# Wait for the transaction to be mined, and get the transaction receipt +tx_receipt = platon.waitForTransactionReceipt(tx_hash1) +print(tx_receipt) +# hrpgot, data = bech32.decode("lax", from_address) +# address = to_checksum_address(bytes(data)) +# print(address) +address = "lax1yjjzvjph3tw4h2quw6mse25y492xy7fzwdtqja" +# # Display the default greeting from the contract + +print('get : {}'.format( + payable.functions.get().call() +)) \ No newline at end of file diff --git a/tests/WasmTest2.py b/tests/WasmTest2.py new file mode 100644 index 0000000..e2d9a97 --- /dev/null +++ b/tests/WasmTest2.py @@ -0,0 +1,78 @@ +from hexbytes import HexBytes +from client_sdk_python import Web3, HTTPProvider +from client_sdk_python.eth import PlatON +import binascii +# f = open('D:/juzhen/HelloWorld.wasm','rb') +# f = open('D:/juzhen/SimpleStorage.wasm','rb') +# f = open('D:/juzhen/PagingQuery2.wasm','rb') +f = open('D:/juzhen/Simplewasm.wasm','rb') +contents=f.read() +b_contents=binascii.b2a_hex(contents) +bytecode=str(b_contents,encoding="utf-8") +print(bytecode) +true = True +false = False +#10.1.1.5 ./keytool genkeypair +# Address: lax1du4w3q0h5gpxh2vpdvtl7m8h2p9qj40a2krhx7 +# PrivateKey: de66562d36f1db46a55f966cfb0eb0981e3e219aa6050612e9f3cb29b8b5c89d +# PublicKey : 6c71c6cfaed8732dafe6ce8888165ac6c8a126e286c226d0ea08fcac768ece512d1eeffad2c442ade2376b2c47472dcea7e30882855f5a3557261b95a72ae9d8 + +#10.1.1.8 ./keytool genkeypair +# Address: lax1h6hexqvrpzavrpt0ng2h8jt4zc8g6jq93x9pcc +# PrivateKey: dab5135cec6008caec5b1d45ee73965a5d59e630d8c10c195f347fca26fbdd57 +# PublicKey : 4f94a5c22ac8f652b142c507179a20b2af96279408ffb97bb2e8381590898c8679719ae575401d8cdf3b14ced771e6644dbd21451fd2073a27e2f69f19514841 + +w3 = Web3(HTTPProvider("http://10.1.1.8:6789")) +platon = PlatON(w3) +print(w3.isConnected()) +from_address = "lax1h6hexqvrpzavrpt0ng2h8jt4zc8g6jq93x9pcc" +print(from_address) + +send_privatekey = "dab5135cec6008caec5b1d45ee73965a5d59e630d8c10c195f347fca26fbdd57" +def contract_deploy(bytecode, fromAddress): + bytecode = bytecode + transactionHash = platon.sendTransaction( + { + "from": fromAddress, + "gas": 1000000, + "gasPrice": 1000000000, + "data": bytecode, + } + ) + transactionHash = HexBytes(transactionHash).hex().lower() + return transactionHash + +bytecode='0061736d0100000001480d60027f7f0060017f017f60017f0060027f7f017f60037f7f7f017f60000060037f7f7f0060047f7f7f7f017f60047f7f7f7f0060027f7e006000017f60027f7e017f60017f017e02a9010703656e760c706c61746f6e5f70616e6963000503656e7617706c61746f6e5f6765745f696e7075745f6c656e677468000a03656e7610706c61746f6e5f6765745f696e707574000203656e7617706c61746f6e5f6765745f73746174655f6c656e677468000303656e7610706c61746f6e5f6765745f7374617465000703656e7610706c61746f6e5f7365745f7374617465000803656e760d706c61746f6e5f72657475726e0000034e4d05000003030307000201000201050104060201000c000101010902000b0203030507010201000003090404060002000104000003000403020000080001000407020406020000050601010800000405017001030305030100020608017f0141d088040b073904066d656d6f72790200115f5f7761736d5f63616c6c5f63746f727300070f5f5f66756e63735f6f6e5f65786974002706696e766f6b6500140908010041010b0208080ac9644d0400104d0b0b00200041186a200110090b800101027f230041206b22032400024020002802042202200028020847044020022001100b1a2000200028020441246a3602040c010b200341086a2000200220002802006b41246d220241016a100c2002200041086a100d22022802082001100b1a2002200228020841246a36020820002002100e2002100f0b200341206a24000ba10101037f20004200370200200041086a2202410036020020012d0000410171450440200020012902003702002002200141086a28020036020020000f0b20012802082103024020012802042201410a4d0440200020014101743a0000200041016a21020c010b200141106a4170712204101321022000200136020420002004410172360200200020023602080b200220032001104e200120026a41003a000020000b250020002001100a1a2000410c6a2001410c6a100a1a200041186a200141186a100a1a20000b2f01017f2001200028020820002802006b41246d2200410174220220022001491b41c7e3f138200041e3f1b81c491b0b4c01017f2000410036020c200041106a2003360200200104402001101021040b2000200436020020002004200241246c6a220236020820002004200141246c6a36020c2000200236020420000b900101027f2000280204210220002802002103034020022003464504402001280204415c6a2002415c6a2202101120012001280204415c6a3602040c010b0b200028020021022000200128020436020020012002360204200028020421022000200128020836020420012002360208200028020821022000200128020c3602082001200236020c200120012802043602000b2b01027f200028020821012000280204210203402001200247044020002001415c6a22013602080c010b0b0b0900200041246c10130b620020002001290200370200200041086a200141086a28020036020020011012200041146a200141146a2802003602002000200129020c37020c2001410c6a1012200041206a200141206a28020036020020002001290218370218200141186a10120b2201017f03402001410c470440200020016a4100360200200141046a21010c010b0b0b0b002000410120001b10150b9f0602057f017e230041a0016b22002400104d10012201101522031002200041206a200041086a200320011016220241001017200041206a101802400240200041206a1019450d002000280224450d0020002802202d000041c001490d010b10000b20004180016a200041206a101a200028028401220141094f044010000b20002802800121030340200104402001417f6a210120033100002005420886842105200341016a21030c010b0b024002402005500d00418008101b200551044020024101101c0c020b418508101b200551044020024102101c0c020b419108101b20055104402002101d410147044010000b200041206a101e21032000413c6a280200210220002802382104200041d8006a101f210120004198016a410036020020004190016a420037030020004188016a4200370300200042003703800120004180016a200220046b41246d41ff0171ad22051020200028028001210220004180016a4104721021200120021022200120051023220128020c200141106a28020047044010000b200128020020012802041006200128020c22020440200120023602100b200310240c020b41a208101b2005520d002002101d410247044010000b200041206a200241011017200041206a101802400240200041206a1019450d002000280224450d0020002802202d000041c001490d010b10000b20004180016a200041206a101a200028028401220141024f044010000b4100210220002802800121030340200104402001417f6a210120032d00002102200341016a21030c010b0b200041206a101e2103200041c8006a200041206a280218200241ff017141246c6a410c6a100a1a200041d8006a101f210120004198016a410036020020004190016a420037030020004188016a4200370300200042003703800120004180016a200041f0006a200041c8006a100a102521022000280280012104200241046a1021200120041022200120004180016a200041c8006a100a1026220128020c200141106a28020047044010000b200128020020012802041006200128020c22020440200120023602100b200310240c010b10000b1027200041a0016a24000b9b0101047f230041106b220124002001200036020c2000047f41c808200041086a2202411076220041c8082802006a220336020041c40841c408280200220420026a41076a417871220236020002400240200341107420024d044041c808200341016a360200200041016a21000c010b2000450d010b200040000d0010000b20042001410c6a4104103c41086a0541000b2100200141106a240020000b0c00200020012002411c10280bc90202067f017e230041106b220324002001280208220520024b0440200341086a2001102d20012003280208200328020c102e36020c20032001102d410021052001027f410020032802002207450d001a410020032802042208200128020c2206490d001a200820062006417f461b210420070b360210200141146a2004360200200141003602080b200141106a210603402001280214210402402005200249044020040d01410021040b200020062802002004411410281a200341106a24000f0b20032001102d41002104027f410020032802002205450d001a410020032802042208200128020c2207490d001a200820076b2104200520076a0b2105200120043602142001200536021020032006410020052004102e10512001200329030022093702102001200128020c2009422088a76a36020c2001200128020841016a22053602080c000b000b4101017f200028020445044010000b0240200028020022012d0000418101470d00200028020441014d047f100020002802000520010b2c00014100480d0010000b0b980101037f200028020445044041000f0b20001018200028020022022c0000220141004e044020014100470f0b027f4101200141807f460d001a200141ff0171220341b7014d0440200028020441014d047f100020002802000520020b2d00014100470f0b4100200341bf014b0d001a2000280204200141ff017141ca7e6a22014d047f100020002802000520020b20016a2d00004100470b0bd50101047f200110292204200128020422024b04401000200128020421020b200128020021052000027f02400240200204404100210120052c00002203417f4a0d01027f200341ff0171220141bf014d04404100200341ff017141b801490d011a200141c97e6a0c010b4100200341ff017141f801490d001a200141897e6a0b41016a21010c010b4101210120050d000c010b41002103200120046a20024b0d0020022001490d00410020022004490d011a200120056a2103200220016b20042004417f461b0c010b41000b360204200020033602000b3901027e42a5c688a1c89ca7f94b210103402000300000220250450440200041016a2100200142b383808080207e20028521010c010b0b20010b6701027f23004180016b22022400200241306a102a200241306a102b21032000101d410247044010000b200241086a200041011017200241086a2003102c200241086a101e2100200241086a200241d8006a2003100b20011100002000102420024180016a24000b800101047f230041106b2201240002402000280204450d0020002802002d000041c001490d00200141086a2000102d200128020c210003402000450d01200141002001280208220320032000102e22046a20034520002004497222031b3602084100200020046b20031b2100200241016a21020c000b000b200141106a240020020be906010c7f230041b0016b22042400200042003702182000428ed1dd82cbd38f9ca07f3703102000410036020820004200370200200041206a4100360200200441206a101f22072000290310102f200728020c200741106a28020047044010000b200041186a21052000411c6a21090240200728020022022007280204220810032206450d002006101321030340200120036a41003a00002006200141016a2201470d000b20022008200320011004417f460440410021010c010b02400240200441086a200341016a200120036a2003417f736a10162203280204450d0020032802002d000041c001490d002003101d21012000280220200028021822026b41246d20014904402005200441386a2001200028021c20026b41246d200041206a100d2201100e2001100f0b20044188016a2003410110302101200441f8006a2003410010302108200041206a210b20012802042103034020082802042003464100200128020822022008280208461b0d02200441e0006a20032002411c1028200441386a102b2203102c0240200028021c220220002802204904402002200310112009200928020041246a3602000c010b20044198016a2005200220052802006b41246d220241016a100c2002200b100d210220042802a00120031011200420042802a00141246a3602a00120052002100e2002100f0b20012001280204220320012802086a410020031b22033602042001280200220204402001200236020820032002102e210a2001027f2001280204220c4504404100210241000c010b41002102410020012802082203200a490d001a2003200a200a417f461b2102200c0b2203ad2002ad42208684370204200141002001280200220a20026b22022002200a4b1b3602000c0105200141003602080c010b000b000b10000b200621010b200728020c22030440200720033602100b024020010d0020002802042206200028020022036b41246d22022000280220200028021822016b41246d4d04402002200928020020016b41246d22084b044020032003200841246c6a2202200110311a20022006200910320c020b2005200320062001103110330c010b200104402005103420004100360220200042003702180b200020052002100c2202101022013602182000200136021c20002001200241246c6a36022020032006200910320b200441b0016a240020000b29002000410036020820004200370200200041001035200041146a41003602002000420037020c20000b840102027f017e4101210320014280015a0440034020012004845045044020044238862001420888842101200241016a2102200442088821040c010b0b200241384f047f2002103620026a0520020b41016a21030b200041186a28020022020440200041086a280200200041146a2802002002103721000b2000200028020020036a3602000bea0101047f230041106b22042400200028020422012000280210220241087641fcffff07716a2103027f410020012000280208460d001a2003280200200241ff07714102746a0b2101200441086a20001038200428020c210203400240200120024604402000410036021420002802082103200028020421010340200320016b41027522024103490d022000200141046a22013602040c000b000b200141046a220120032802006b418020470d0120032802042101200341046a21030c010b0b2002417f6a220241014d04402000418004418008200241016b1b3602100b200020011039200441106a24000b1300200028020820014904402000200110350b0bbc0202037f037e024020015004402000418001103f0c010b20014280015a044020012107034020062007845045044020064238862007420888842107200241016a2102200642088821060c010b0b0240200241384f04402002210303402003044020034108762103200441016a21040c010b0b200441c9004f044010000b2000200441b77f6a41ff0171103f2000200028020420046a1053200028020420002802006a417f6a21042002210303402003450d02200420033a0000200341087621032004417f6a21040c000b000b200020024180017341ff0171103f0b2000200028020420026a1053200028020420002802006a417f6a210203402001200584500d02200220013c0000200542388620014208888421012002417f6a2102200542088821050c000b000b20002001a741ff0171103f0b20004101104220000be206010d7f230041b0016b22012400200141186a101f2106200141a8016a22024100360200200141a0016a2205420037030020014198016a22044200370300200142003703900120014190016a20002903101020200128029001210720014190016a410472102120062007102220062000290310102f200628020c200641106a28020047044010000b200628020421092006280200210a2001101f21032002410036020020054200370300200442003703002001420037039001027f20002802182000411c6a280200460440200141013602900141010c010b20014190016a4100103a2107200028021c200028021822026b2105037f2005047f20074100103a22042002103b2004200141d0006a2002410c6a100a102520014180016a200241186a100a10254101103a1a2005415c6a2105200241246a21020c010520074101103a1a2001280290010b0b0b210420014190016a410472102141011013220241fe013a0000200328020c200341106a28020047044010000b200241016a21072003280204220541016a220820032802084b047f20032008103520032802040520050b20032802006a20024101103c1a2003200328020441016a3602042003200420026b20076a10222003200028021c20002802186b41246d103d210b200028021c200028021822026b2105200141d0006a410472210c20014190016a410472210d034020050440200b4103103d210420014100360268200142003703602001420037035820014200370350200141d0006a2002103b200141d0006a200141406b2002410c6a2207100a1025200141306a200241186a2208100a10251a20042001280250102220044101103d2104200141003602a801200142003703a0012001420037039801200142003703900120014190016a20014180016a2002100a10251a200420012802900110222004200141f0006a2002100a10262104200d1021200420014190016a2007100a102620014180016a2008100a10261a200c10212005415c6a2105200241246a21020c010b0b0240200328020c2003280210460440200328020021020c010b100020032802002102200328020c2003280210460d0010000b200a2009200220032802041005200328020c22020440200320023602100b200628020c22020440200620023602100b200041186a103e2000103e200141b0016a24000ba10101037f41012103024002400240200128020420012d00002202410176200241017122041b220241014d0440200241016b0d032001280208200141016a20041b2c0000417f4c0d010c030b200241374b0d010b200241016a21030c010b2002103620026a41016a21030b027f200041186a28020022010440200041086a280200200041146a280200200110370c010b20000b2201200128020020036a36020020000b910101047f410121022001280208200141016a20012d0000220441017122051b210302400240024002402001280204200441017620051b2201410146044020032c000022014100480d012000200141ff0171103f0c040b200141374b0d01200121020b200020024180017341ff0171103f0c010b200020011040200121020b200020032002410010410b20004101104220000b880101037f41b408410136020041b8082802002100034020000440034041bc0841bc082802002201417f6a2202360200200141014845044041b4084100360200200020024102746a22004184016a280200200041046a28020011020041b408410136020041b80828020021000c010b0b41bc08412036020041b808200028020022003602000c010b0b0b730020004200370210200042ffffffff0f370208200020023602042000200136020002402003410871450d002000104f20024f0d002003410471044010000c010b200042003702000b02402003411071450d002000104f20024d0d0020034104710440100020000f0b200042003702000b20000bff0201037f200028020445044041000f0b2000101841012102024020002802002c00002201417f4a0d00200141ff0171220341b7014d0440200341807f6a0f0b02400240200141ff0171220141bf014d0440024020002802042201200341c97e6a22024d047f100020002802040520010b4102490d0020002802002d00010d0010000b200241054f044010000b20002802002d000145044010000b4100210241b7012101034020012003460440200241384f0d030c0405200028020020016a41ca7e6a2d00002002410874722102200141016a21010c010b000b000b200141f7014d0440200341c07e6a0f0b024020002802042201200341897e6a22024d047f100020002802040520010b4102490d0020002802002d00010d0010000b200241054f044010000b20002802002d000145044010000b4100210241f701210103402001200346044020024138490d0305200028020020016a418a7e6a2d00002002410874722102200141016a21010c010b0b0b200241ff7d490d010b10000b20020bc50201027f200041003a0000200041246a2202417f6a41003a0000200041003a0002200041003a00012002417d6a41003a00002002417e6a41003a0000200041003a00032002417c6a41003a00002000410020006b41037122016a220241003602002002412420016b417c7122016a2200417c6a4100360200024020014109490d002002410036020820024100360204200041786a4100360200200041746a410036020020014119490d002002410036021820024100360214200241003602102002410036020c200041706a41003602002000416c6a4100360200200041686a4100360200200041646a41003602002001200241047141187222016b2100200120026a2101034020004120490d0120014200370300200141186a4200370300200141106a4200370300200141086a4200370300200141206a2101200041606a21000c000b000b0b16002000104a2000410c6a104a200041186a104a20000b5e01017f230041306b220224002002200041001017200241186a200241001017200241186a2001104b200241186a200041011017200241186a2001410c6a104b200241186a200041021017200241186a200141186a104b200241306a24000b2101017f20011029220220012802044b044010000b2000200120011050200210510b2701017f230041206b22022400200241086a2000200141141028104f2100200241206a240020000b09002000200110231a0be70101037f230041106b2204240020004200370200200041086a410036020020012802042103024002402002450440200321020c010b410021022003450d002003210220012802002d000041c001490d00200441086a2001102d20004100200428020c2201200428020822022001102e22032003417f461b20024520012003497222031b220536020820004100200220031b3602042000200120056b3602000c010b20012802002103200128020421012000410036020020004100200220016b20034520022001497222021b36020820004100200120036a20021b3602040b200441106a240020000b3e000340200020014645044020022000104c2002410c6a2000410c6a104c200241186a200041186a104c200241246a2102200041246a21000c010b0b20020b2e000340200020014645044020022802002000100b1a2002200228020041246a360200200041246a21000c010b0b0b0900200020013602040b0b002000200028020010330b2f01017f200028020820014904402001101520002802002000280204103c210220002001360208200020023602000b0b1e01017f03402000044020004108762100200141016a21010c010b0b20010b25002000200120026a417f6a220241087641fcffff07716a280200200241ff07714102746a0b4f01037f20012802042203200128021020012802146a220441087641fcffff07716a21022000027f410020032001280208460d001a2002280200200441ff07714102746a0b360204200020023602000b2501017f200028020821020340200120024645044020002002417c6a22023602080c010b0b0bc30c02077f027e230041306b22042400200041046a2107027f20014101460440200041086a280200200041146a280200200041186a220228020022031037280200210120022003417f6a360200200710434180104f044020072000410c6a280200417c6a10390b200141384f047f2001103620016a0520010b41016a2102200041186a28020022010440200041086a280200200041146a280200200110370c020b20000c010b0240200710430d00200041146a28020022014180084f0440200020014180786a360214200041086a2201280200220228020021032001200241046a360200200420033602182007200441186a10440c010b2000410c6a2802002202200041086a2802006b4102752203200041106a2205280200220620002802046b220141027549044041802010132105200220064704400240200028020c220120002802102202470d0020002802082203200028020422064b04402000200320012003200320066b41027541016a417e6d41027422026a1045220136020c2000200028020820026a3602080c010b200441186a200220066b2201410175410120011b22012001410276200041106a10462102200028020c210320002802082101034020012003470440200228020820012802003602002002200228020841046a360208200141046a21010c010b0b200029020421092000200229020037020420022009370200200029020c21092000200229020837020c2002200937020820021047200028020c21010b200120053602002000200028020c41046a36020c0c020b02402000280208220120002802042202470d00200028020c2203200028021022064904402000200120032003200620036b41027541016a41026d41027422026a104822013602082000200028020c20026a36020c0c010b200441186a200620026b2201410175410120011b2201200141036a410276200041106a10462102200028020c210320002802082101034020012003470440200228020820012802003602002002200228020841046a360208200141046a21010c010b0b200029020421092000200229020037020420022009370200200029020c21092000200229020837020c2002200937020820021047200028020821010b2001417c6a2005360200200020002802082201417c6a22023602082002280200210220002001360208200420023602182007200441186a10440c010b20042001410175410120011b200320051046210241802010132106024020022802082201200228020c2203470d0020022802042205200228020022084b04402002200520012005200520086b41027541016a417e6d41027422036a104522013602082002200228020420036a3602040c010b200441186a200320086b2201410175410120011b22012001410276200241106a280200104621032002280208210520022802042101034020012005470440200328020820012802003602002003200328020841046a360208200141046a21010c010b0b20022902002109200220032902003702002003200937020020022902082109200220032902083702082003200937020820031047200228020821010b200120063602002002200228020841046a360208200028020c2105034020002802082005460440200028020421012000200228020036020420022001360200200228020421012002200536020420002001360208200029020c21092000200229020837020c2002200937020820021047052005417c6a210502402002280204220120022802002203470d0020022802082206200228020c22084904402002200120062006200820066b41027541016a41026d41027422036a104822013602042002200228020820036a3602080c010b200441186a200820036b2201410175410120011b2201200141036a4102762002280210104621062002280208210320022802042101034020012003470440200428022020012802003602002004200428022041046a360220200141046a21010c010b0b20022902002109200220042903183702002002290208210a20022004290320370208200420093703182004200a37032020061047200228020421010b2001417c6a200528020036020020022002280204417c6a3602040c010b0b0b200441186a20071038200428021c410036020041012102200041186a0b2201200128020020026a360200200441306a240020000b2701017f230041106b2202240020004100103a20022001100a10254101103a1a200241106a24000bfc0801067f03400240200020046a2105200120046a210320022004460d002003410371450d00200520032d00003a0000200441016a21040c010b0b200220046b210602402005410371220745044003402006411049450440200020046a2203200120046a2205290200370200200341086a200541086a290200370200200441106a2104200641706a21060c010b0b027f2006410871450440200120046a2103200020046a0c010b200020046a2205200120046a2204290200370200200441086a2103200541086a0b21042006410471044020042003280200360200200341046a2103200441046a21040b20064102710440200420032f00003b0000200341026a2103200441026a21040b2006410171450d01200420032d00003a000020000f0b024020064120490d002007417f6a220741024b0d00024002400240024002400240200741016b0e020102000b2005200120046a220328020022073a0000200541016a200341016a2f00003b0000200041036a2108200220046b417d6a2106034020064111490d03200420086a2203200120046a220541046a2802002202410874200741187672360200200341046a200541086a2802002207410874200241187672360200200341086a2005410c6a28020022024108742007411876723602002003410c6a200541106a2802002207410874200241187672360200200441106a2104200641706a21060c000b000b2005200120046a220328020022073a0000200541016a200341016a2d00003a0000200041026a2108200220046b417e6a2106034020064112490d03200420086a2203200120046a220541046a2802002202411074200741107672360200200341046a200541086a2802002207411074200241107672360200200341086a2005410c6a28020022024110742007411076723602002003410c6a200541106a2802002207411074200241107672360200200441106a2104200641706a21060c000b000b2005200120046a28020022073a0000200041016a21082004417f7320026a2106034020064113490d03200420086a2203200120046a220541046a2802002202411874200741087672360200200341046a200541086a2802002207411874200241087672360200200341086a2005410c6a28020022024118742007410876723602002003410c6a200541106a2802002207411874200241087672360200200441106a2104200641706a21060c000b000b200120046a41036a2103200020046a41036a21050c020b200120046a41026a2103200020046a41026a21050c010b200120046a41016a2103200020046a41016a21050b20064110710440200520032d00003a00002005200328000136000120052003290005370005200520032f000d3b000d200520032d000f3a000f200541106a2105200341106a21030b2006410871044020052003290000370000200541086a2105200341086a21030b2006410471044020052003280000360000200541046a2105200341046a21030b20064102710440200520032f00003b0000200541026a2105200341026a21030b2006410171450d00200520032d00003a00000b20000b8c0201057f2001044020002802042105200041106a2802002202200041146a280200220349044020022001ad2005ad422086843702002000200028021041086a36021020000f0b027f41002002200028020c22046b410375220641016a2202200320046b2203410275220420042002491b41ffffffff01200341037541ffffffff00491b2204450d001a200441037410130b2102200220064103746a22032001ad2005ad4220868437020020032000280210200028020c22066b22016b2105200220044103746a2102200341086a2103200141014e0440200520062001103c1a0b20002002360214200020033602102000200536020c20000f0b200041c001103f2000410041004101104120000b0e0020002802000440200010340b0b2500200041011052200028020020002802046a20013a00002000200028020441016a3602040b5e01027f20011036220241b7016a22034180024e044010000b2000200341ff0171103f2000200028020420026a1053200028020420002802006a417f6a2100034020010440200020013a0000200141087621012000417f6a21000c010b0b0b2d00200020021052200028020020002802046a20012002103c1a2000200028020420026a3602042000200310420b820201047f02402001450d00034020002802102202200028020c460d01200241786a28020020014904401000200028021021020b200241786a2203200328020020016b220136020020010d012000200336021020004101200028020422032002417c6a28020022016b22021036220441016a20024138491b220520036a1053200120002802006a220320056a2003200210490240200241374d0440200028020020016a200241406a3a00000c010b200441f7016a220341ff014d0440200028020020016a20033a00002000280200200120046a6a210103402002450d02200120023a0000200241087621022001417f6a21010c000b000b10000b410121010c000b000b0b2801017f200028020820002802046b2201410874417f6a410020011b200028021420002802106a6b0ba10202057f017e230041206b22052400024020002802082202200028020c2203470d0020002802042204200028020022064b04402000200420022004200420066b41027541016a417e6d41027422036a104522023602082000200028020420036a3602040c010b200541086a200320066b2202410175410120021b220220024102762000410c6a10462103200028020821042000280204210203402002200446450440200328020820022802003602002003200328020841046a360208200241046a21020c010b0b20002902002107200020032902003702002003200737020020002902082107200020032902083702082003200737020820031047200028020821020b200220012802003602002000200028020841046a360208200541206a24000b2501017f200120006b220141027521032001044020022000200110490b200220034102746a0b4f01017f2000410036020c200041106a2003360200200104402001410274101321040b200020043602002000200420024102746a22023602082000200420014102746a36020c2000200236020420000b2b01027f200028020821012000280204210203402001200247044020002001417c6a22013602080c010b0b0b1b00200120006b22010440200220016b22022000200110490b20020b8d0301037f024020002001460d00200120006b20026b410020024101746b4d0440200020012002103c1a0c010b20002001734103712103027f024020002001490440200020030d021a410021030340200120036a2105200020036a2204410371450440200220036b210241002103034020024104490d04200320046a200320056a280200360200200341046a21032002417c6a21020c000b000b20022003460d04200420052d00003a0000200341016a21030c000b000b024020030d002001417f6a21040340200020026a22034103714504402001417c6a21032000417c6a2104034020024104490d03200220046a200220036a2802003602002002417c6a21020c000b000b2002450d042003417f6a200220046a2d00003a00002002417f6a21020c000b000b2001417f6a210103402002450d03200020026a417f6a200120026a2d00003a00002002417f6a21020c000b000b200320056a2101200320046a0b210303402002450d01200320012d00003a00002002417f6a2102200341016a2103200141016a21010c000b000b0b170020004200370200200041086a4100360200200010120bf30201057f230041206b22022400024002402000280204044020002802002d000041c001490d010b200241086a104a0c010b200241186a2000101a2000102921030240024002400240200228021822000440200228021c220520034f0d010b41002100200241106a410036020020024200370308410021050c010b200241106a4100360200200242003703082000200520032003417f461b22046a21052004410a4b0d010b200220044101743a0008200241086a41017221030c010b200441106a4170712206101321032002200436020c20022006410172360208200220033602100b03402000200546450440200320002d00003a0000200341016a2103200041016a21000c010b0b200341003a00000b024020012d0000410171450440200141003b01000c010b200128020841003a00002001410036020420012d0000410171450d00200141003602000b20012002290308370200200141086a200241106a280200360200200241086a1012200241206a24000b8c0201047f20002001470440200128020420012d00002202410176200241017122041b2102200141016a210320012802082105410a21012005200320041b210420002d0000410171220304402000280200417e71417f6a21010b200220014d0440027f2003044020002802080c010b200041016a0b21012002044020012004200210490b200120026a41003a000020002d00004101710440200020023602040f0b200020024101743a00000f0b416f2103200141e6ffffff074d0440410b20014101742201200220022001491b220141106a4170712001410b491b21030b20031013220120042002104e200020023602042000200341017236020020002001360208200120026a41003a00000b0b3501017f230041106b220041d0880436020c41c008200028020c41076a417871220036020041c408200036020041c8083f003602000b100020020440200020012002103c1a0b0b2e01017f200028020445044041000f0b4101210120002802002c0000417f4c047f20001050200010296a0520010b0b5b00027f027f41002000280204450d001a410020002802002c0000417f4a0d011a20002802002d0000220041bf014d04404100200041b801490d011a200041c97e6a0c010b4100200041f801490d001a200041897e6a0b41016a0b0b5b01027f2000027f0240200128020022054504400c010b200220036a200128020422014b0d0020012002490d00410020012003490d011a200220056a2104200120026b20032003417f461b0c010b41000b360204200020043602000b1b00200028020420016a220120002802084b04402000200110350b0b0f00200020011035200020013602040b0b3901004180080b32696e6974006164645f6d657373616765006765745f6d6573736167655f73697a65006765745f6d6573736167655f626f64790a' +abi=[{"baseclass":[],"fields":[{"name":"head","type":"string"}],"name":"message","type":"struct"},{"baseclass":["message"],"fields":[{"name":"body","type":"string"},{"name":"end","type":"string"}],"name":"my_message","type":"struct"},{"constant":false,"input":[{"name":"one_message","type":"my_message"}],"name":"init","output":"void","type":"Action"},{"constant":false,"input":[{"name":"one_message","type":"my_message"}],"name":"add_message","output":"void","type":"Action"},{"constant":true,"input":[],"name":"get_message_size","output":"uint8","type":"Action"},{"constant":true,"input":[{"name":"index","type":"uint8"}],"name":"get_message_body","output":"string","type":"Action"}] +print(type(abi)) + +tx = contract_deploy(bytecode, from_address) +print(tx) +tx_receipt = platon.waitForTransactionReceipt(tx) +print(tx_receipt) +contractAddress = tx_receipt.contractAddress +print(contractAddress) + +def SendTxn(txn): + signed_txn = platon.account.signTransaction(txn,private_key=send_privatekey) + res = platon.sendRawTransaction(signed_txn.rawTransaction).hex() + txn_receipt = platon.waitForTransactionReceipt(res) + print(res) + return txn_receipt + +contract_instance = platon.contract(address=contractAddress, abi=abi) + +txn = contract_instance.functions.ifControl(20).buildTransaction( + { + 'chainId':200, + 'nonce':platon.getTransactionCount(from_address), + 'gas':2000000, + 'value':0, + 'gasPrice':1000000000, + } +) + +print(SendTxn(txn)) + +result = contract_instance.functions.getIfControlResult().call() +print(result) diff --git a/tests/conftest.py b/tests/conftest.py index df38f6d..c194d83 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,23 +1,108 @@ import pytest +import time +import warnings -from eth_utils import ( - to_bytes, +from client_sdk_python.providers.eth_tester import ( + EthereumTesterProvider, ) - -from client_sdk_python.utils.toolz import ( - identity, +from client_sdk_python.utils.threads import ( + Timeout, ) +from client_sdk_python.main import Web3 + + +class PollDelayCounter: + def __init__(self, initial_delay=0, max_delay=1, initial_step=0.01): + self.initial_delay = initial_delay + self.initial_step = initial_step + self.max_delay = max_delay + self.current_delay = initial_delay + + def __call__(self): + delay = self.current_delay + + if self.current_delay == 0: + self.current_delay += self.initial_step + else: + self.current_delay *= 2 + self.current_delay = min(self.current_delay, self.max_delay) + + return delay + + def reset(self): + self.current_delay = self.initial_delay + + +@pytest.fixture() +def sleep_interval(): + return PollDelayCounter() + + +def is_all_testrpc_providers(providers): + return all( + isinstance(provider, EthereumTesterProvider) + for provider + in providers + ) -from .utils import ( - get_open_port, -) +@pytest.fixture() +def skip_if_testrpc(): + + def _skip_if_testrpc(web3): + if is_all_testrpc_providers(web3.providers): + pytest.skip() + return _skip_if_testrpc -@pytest.fixture(scope="module", params=[lambda x: to_bytes(hexstr=x), identity]) -def address_conversion_func(request): - return request.param + +@pytest.fixture() +def wait_for_miner_start(): + def _wait_for_miner_start(web3, timeout=60): + poll_delay_counter = PollDelayCounter() + with Timeout(timeout) as timeout: + while not web3.eth.mining or not web3.eth.hashrate: + time.sleep(poll_delay_counter()) + timeout.check() + return _wait_for_miner_start + + +@pytest.fixture() +def wait_for_block(): + def _wait_for_block(web3, block_number=1, timeout=None): + if not timeout: + timeout = (block_number - web3.eth.blockNumber) * 3 + poll_delay_counter = PollDelayCounter() + with Timeout(timeout) as timeout: + while True: + if web3.eth.blockNumber >= block_number: + break + web3.manager.request_blocking("evm_mine", []) + timeout.sleep(poll_delay_counter()) + return _wait_for_block @pytest.fixture() -def open_port(): - return get_open_port() +def wait_for_transaction(): + def _wait_for_transaction(web3, txn_hash, timeout=120): + poll_delay_counter = PollDelayCounter() + with Timeout(timeout) as timeout: + while True: + txn_receipt = web3.eth.getTransactionReceipt(txn_hash) + if txn_receipt is not None: + break + time.sleep(poll_delay_counter()) + timeout.check() + + return txn_receipt + return _wait_for_transaction + + +@pytest.fixture() +def web3(): + provider = EthereumTesterProvider() + return Web3(provider) + + +@pytest.fixture(autouse=True) +def print_warnings(): + warnings.simplefilter('always') diff --git a/tests/core/admin-module/test_admin_setSolc.py b/tests/core/admin-module/test_admin_setSolc.py index 850a907..55b9360 100644 --- a/tests/core/admin-module/test_admin_setSolc.py +++ b/tests/core/admin-module/test_admin_setSolc.py @@ -1,7 +1,7 @@ import pytest import subprocess -from eth_utils import ( +from client_sdk_python.packages.eth_utils import ( to_text, ) diff --git a/tests/core/caching-utils/test_generate_cache_key.py b/tests/core/caching-utils/test_generate_cache_key.py index 7659702..87ff23e 100644 --- a/tests/core/caching-utils/test_generate_cache_key.py +++ b/tests/core/caching-utils/test_generate_cache_key.py @@ -1,6 +1,6 @@ import random -from eth_utils import ( +from client_sdk_python.packages.eth_utils import ( to_dict, ) from hypothesis import ( diff --git a/tests/core/contracts/conftest.py b/tests/core/contracts/conftest.py index ca14b2d..6645c73 100644 --- a/tests/core/contracts/conftest.py +++ b/tests/core/contracts/conftest.py @@ -2,7 +2,7 @@ import json import pytest -from eth_utils import ( +from client_sdk_python.packages.eth_utils import ( event_signature_to_log_topic, ) diff --git a/tests/core/contracts/test_concise_contract.py b/tests/core/contracts/test_concise_contract.py index 7f00f23..a811852 100644 --- a/tests/core/contracts/test_concise_contract.py +++ b/tests/core/contracts/test_concise_contract.py @@ -3,7 +3,7 @@ Mock, ) -from eth_utils import ( +from client_sdk_python.packages.eth_utils import ( decode_hex, ) diff --git a/tests/core/contracts/test_contract_class_construction.py b/tests/core/contracts/test_contract_class_construction.py index 4492ade..7a9f179 100644 --- a/tests/core/contracts/test_contract_class_construction.py +++ b/tests/core/contracts/test_contract_class_construction.py @@ -1,7 +1,7 @@ import json import pytest -from eth_utils import ( +from client_sdk_python.packages.eth_utils import ( decode_hex, ) diff --git a/tests/core/contracts/test_contract_constructor.py b/tests/core/contracts/test_contract_constructor.py index 62995de..56ef3c8 100644 --- a/tests/core/contracts/test_contract_constructor.py +++ b/tests/core/contracts/test_contract_constructor.py @@ -1,6 +1,6 @@ import pytest -from eth_utils import ( +from client_sdk_python.packages.eth_utils import ( decode_hex, ) diff --git a/tests/core/contracts/test_contract_constructor_encoding.py b/tests/core/contracts/test_contract_constructor_encoding.py index edd7383..56ec66d 100644 --- a/tests/core/contracts/test_contract_constructor_encoding.py +++ b/tests/core/contracts/test_contract_constructor_encoding.py @@ -1,9 +1,9 @@ import pytest -from eth_abi import ( +from client_sdk_python.packages.eth_abi import ( encode_abi, ) -from eth_utils import ( +from client_sdk_python.packages.eth_utils import ( encode_hex, remove_0x_prefix, ) diff --git a/tests/core/contracts/test_contract_deployment.py b/tests/core/contracts/test_contract_deployment.py index 88cf8b2..b44b0ce 100644 --- a/tests/core/contracts/test_contract_deployment.py +++ b/tests/core/contracts/test_contract_deployment.py @@ -1,7 +1,7 @@ import pytest -from eth_utils import ( +from client_sdk_python.packages.eth_utils import ( decode_hex, ) diff --git a/tests/core/contracts/test_contract_transact_interface.py b/tests/core/contracts/test_contract_transact_interface.py index 4ed2d92..c8777d4 100644 --- a/tests/core/contracts/test_contract_transact_interface.py +++ b/tests/core/contracts/test_contract_transact_interface.py @@ -2,7 +2,7 @@ import pytest -from eth_utils import ( +from client_sdk_python.packages.eth_utils import ( to_bytes, ) diff --git a/tests/core/contracts/test_extracting_event_data.py b/tests/core/contracts/test_extracting_event_data.py index c9fecbb..513068f 100644 --- a/tests/core/contracts/test_extracting_event_data.py +++ b/tests/core/contracts/test_extracting_event_data.py @@ -1,6 +1,6 @@ import pytest -from eth_utils import ( +from client_sdk_python.packages.eth_utils import ( is_same_address, ) diff --git a/tests/core/contracts/test_extracting_event_data_old.py b/tests/core/contracts/test_extracting_event_data_old.py index 8273f33..2f31800 100644 --- a/tests/core/contracts/test_extracting_event_data_old.py +++ b/tests/core/contracts/test_extracting_event_data_old.py @@ -1,6 +1,6 @@ import pytest -from eth_utils import ( +from client_sdk_python.packages.eth_utils import ( is_same_address, ) diff --git a/tests/core/contracts/test_implicit_contract.py b/tests/core/contracts/test_implicit_contract.py index e258f59..f03c20b 100644 --- a/tests/core/contracts/test_implicit_contract.py +++ b/tests/core/contracts/test_implicit_contract.py @@ -1,6 +1,6 @@ import pytest -from eth_utils import ( +from client_sdk_python.packages.eth_utils import ( is_integer, ) diff --git a/tests/core/eth-module/test_accounts.py b/tests/core/eth-module/test_accounts.py index 160936b..c710096 100644 --- a/tests/core/eth-module/test_accounts.py +++ b/tests/core/eth-module/test_accounts.py @@ -5,7 +5,7 @@ from eth_account.messages import ( defunct_hash_message, ) -from eth_utils import ( +from client_sdk_python.packages.eth_utils import ( is_checksum_address, ) from hexbytes import ( @@ -308,7 +308,7 @@ def test_eth_account_sign_transaction_from_eth_test(acct, transaction_info): # There is some ambiguity about whether `r` will always be deterministically # generated from the transaction hash and private key, mostly due to code # author's ignorance. The example test fixtures and implementations seem to agree, so far. - # See ecdsa_raw_sign() in /eth_keys/backends/native/ecdsa.py + # See ecdsa_raw_sign() in /platon_keys/backends/native/ecdsa.py signed = acct.signTransaction(transaction, key) assert signed.r == Web3.toInt(hexstr=expected_raw_txn[-130:-66]) diff --git a/tests/core/eth-module/test_eth_contract.py b/tests/core/eth-module/test_eth_contract.py index 3cfc9f2..5150286 100644 --- a/tests/core/eth-module/test_eth_contract.py +++ b/tests/core/eth-module/test_eth_contract.py @@ -3,7 +3,7 @@ Mock, ) -from eth_utils import ( +from client_sdk_python.packages.eth_utils import ( to_bytes, ) diff --git a/tests/core/filtering/conftest.py b/tests/core/filtering/conftest.py index c5538cb..4ba1c51 100644 --- a/tests/core/filtering/conftest.py +++ b/tests/core/filtering/conftest.py @@ -2,7 +2,7 @@ import json import pytest -from eth_utils import ( +from client_sdk_python.packages.eth_utils import ( apply_key_map, encode_hex, event_signature_to_log_topic, diff --git a/tests/core/filtering/test_contract_on_event_filtering.py b/tests/core/filtering/test_contract_on_event_filtering.py index 48112d0..23e7b23 100644 --- a/tests/core/filtering/test_contract_on_event_filtering.py +++ b/tests/core/filtering/test_contract_on_event_filtering.py @@ -1,6 +1,6 @@ import pytest -from eth_utils import ( +from client_sdk_python.packages.eth_utils import ( is_address, ) diff --git a/tests/core/filtering/test_contract_past_event_filtering.py b/tests/core/filtering/test_contract_past_event_filtering.py index c9521d2..8c7d37c 100644 --- a/tests/core/filtering/test_contract_past_event_filtering.py +++ b/tests/core/filtering/test_contract_past_event_filtering.py @@ -1,6 +1,6 @@ import pytest -from eth_utils import ( +from client_sdk_python.packages.eth_utils import ( is_same_address, ) diff --git a/tests/core/filtering/test_filters_against_many_blocks.py b/tests/core/filtering/test_filters_against_many_blocks.py index 6653ad9..4a32e0d 100644 --- a/tests/core/filtering/test_filters_against_many_blocks.py +++ b/tests/core/filtering/test_filters_against_many_blocks.py @@ -1,7 +1,7 @@ import pytest import random -from eth_utils import ( +from client_sdk_python.packages.eth_utils import ( to_tuple, ) diff --git a/tests/core/middleware/test_latest_block_based_cache_middleware.py b/tests/core/middleware/test_latest_block_based_cache_middleware.py index 13513d0..073207e 100644 --- a/tests/core/middleware/test_latest_block_based_cache_middleware.py +++ b/tests/core/middleware/test_latest_block_based_cache_middleware.py @@ -4,7 +4,7 @@ import time import uuid -from eth_utils import ( +from client_sdk_python.packages.eth_utils import ( is_integer, to_tuple, ) diff --git a/tests/core/middleware/test_transaction_signing.py b/tests/core/middleware/test_transaction_signing.py index 978f0c2..77b98d8 100644 --- a/tests/core/middleware/test_transaction_signing.py +++ b/tests/core/middleware/test_transaction_signing.py @@ -1,11 +1,11 @@ import pytest -import eth_account -import eth_keys +from client_sdk_python.packages import platon_account +from client_sdk_python.packages import platon_keys from eth_tester.exceptions import ( ValidationError, ) -from eth_utils import ( +from client_sdk_python.packages.eth_utils import ( to_bytes, to_hex, ) diff --git a/tests/core/mining-module/test_miner_setExtra.py b/tests/core/mining-module/test_miner_setExtra.py index 0784eec..92248c1 100644 --- a/tests/core/mining-module/test_miner_setExtra.py +++ b/tests/core/mining-module/test_miner_setExtra.py @@ -1,6 +1,6 @@ import random -from eth_utils import ( +from client_sdk_python.packages.eth_utils import ( decode_hex, ) from flaky import ( diff --git a/tests/core/providers/test_auto_provider.py b/tests/core/providers/test_auto_provider.py index 698914b..eb67386 100644 --- a/tests/core/providers/test_auto_provider.py +++ b/tests/core/providers/test_auto_provider.py @@ -6,7 +6,7 @@ gettempdir, ) -from eth_utils import ( +from client_sdk_python.packages.eth_utils import ( ValidationError, ) diff --git a/tests/core/utilities/test_encoding.py b/tests/core/utilities/test_encoding.py index 110e95d..c96825d 100644 --- a/tests/core/utilities/test_encoding.py +++ b/tests/core/utilities/test_encoding.py @@ -7,7 +7,7 @@ Mock, ) -from eth_utils import ( +from client_sdk_python.packages.eth_utils import ( is_hex, ) from hypothesis import ( diff --git a/tests/core/utilities/test_validation.py b/tests/core/utilities/test_validation.py index 1ff500f..72a9011 100644 --- a/tests/core/utilities/test_validation.py +++ b/tests/core/utilities/test_validation.py @@ -1,6 +1,6 @@ import pytest -from eth_utils import ( +from client_sdk_python.packages.eth_utils import ( to_bytes, ) diff --git a/tests/ens/conftest.py b/tests/ens/conftest.py index 8589597..b49f90a 100644 --- a/tests/ens/conftest.py +++ b/tests/ens/conftest.py @@ -6,8 +6,8 @@ EthereumTester, ) -from ens import ENS -from ens.contract_data import ( +from client_sdk_python.packages.ens import ENS +from client_sdk_python.packages.ens .contract_data import ( registrar_abi, registrar_bytecode, registrar_bytecode_runtime, diff --git a/tests/ens/test_get_registry.py b/tests/ens/test_get_registry.py index 85d3fcc..816b5d9 100644 --- a/tests/ens/test_get_registry.py +++ b/tests/ens/test_get_registry.py @@ -4,7 +4,7 @@ patch, ) -from ens import ENS +from client_sdk_python.packages.ens import ENS from client_sdk_python import Web3 diff --git a/tests/ens/test_nameprep.py b/tests/ens/test_nameprep.py index caa7431..3c3cb30 100644 --- a/tests/ens/test_nameprep.py +++ b/tests/ens/test_nameprep.py @@ -1,7 +1,7 @@ import pytest -from ens import ( +from client_sdk_python.packages.ens import ( InvalidName, ) diff --git a/tests/ens/test_setup_address.py b/tests/ens/test_setup_address.py index 489184a..c71f1dc 100644 --- a/tests/ens/test_setup_address.py +++ b/tests/ens/test_setup_address.py @@ -4,15 +4,15 @@ patch, ) -from eth_utils import ( +from client_sdk_python.packages.eth_utils import ( is_same_address, to_bytes, ) -from ens.constants import ( +from client_sdk_python.packages.ens .constants import ( EMPTY_ADDR_HEX, ) -from ens.main import ( +from client_sdk_python.packages.ens .main import ( UnauthorizedError, ) from client_sdk_python import Web3 diff --git a/tests/ens/test_setup_name.py b/tests/ens/test_setup_name.py index ad71cda..0b376c8 100644 --- a/tests/ens/test_setup_name.py +++ b/tests/ens/test_setup_name.py @@ -1,7 +1,7 @@ import pytest -from ens.main import ( +from client_sdk_python.packages.ens .main import ( AddressMismatch, UnauthorizedError, UnownedName, diff --git a/tests/ens/test_utils.py b/tests/ens/test_utils.py index 4fc3862..974314e 100644 --- a/tests/ens/test_utils.py +++ b/tests/ens/test_utils.py @@ -1,5 +1,5 @@ -from ens.utils import ( +from client_sdk_python.packages.ens .utils import ( init_web3, ) diff --git a/tests/evmcontract_test1.py b/tests/evmcontract_test1.py new file mode 100644 index 0000000..23d906e --- /dev/null +++ b/tests/evmcontract_test1.py @@ -0,0 +1,81 @@ +from hexbytes import HexBytes +from client_sdk_python import Web3, HTTPProvider +from client_sdk_python.eth import PlatON +from client_sdk_python.packages.platon_keys.utils import bech32,address +from client_sdk_python.packages.eth_utils import to_checksum_address + +true = True +false = False + +# w3 = Web3(HTTPProvider("http://10.1.1.5:6789")) +# platon = PlatON(w3) +# print(w3.isConnected()) +# +# from_address = "lax1yjjzvjph3tw4h2quw6mse25y492xy7fzwdtqja" +# print(from_address) +# +# send_privatekey = "16e80ad4079462cc7f9748af2f9cf03e8f7384bed597c086db4f11a98c3b08f0" + +w3 = Web3(HTTPProvider("http://10.1.1.2:6789")) +platon = PlatON(w3) +print(w3.isConnected()) + +from_address = "lax1uqug0zq7rcxddndleq4ux2ft3tv6dqljphydrl" +print(from_address) + +send_privatekey = "983759fe9aac227c535b21d78792d79c2f399b1d43db46ae6d50a33875301557" + +def contract_deploy(bytecode, fromAddress): + bytecode = bytecode + transactionHash = platon.sendTransaction( + { + "from": fromAddress, + "gas": 1000000, + "gasPrice": 1000000000, + "data": bytecode, + } + ) + transactionHash = HexBytes(transactionHash).hex().lower() + return transactionHash + +bytecode = '608060405234801561001057600080fd5b50600060019080600181540180825580915050906001820390600052602060002001600090919290919091505550600060029080600181540180825580915050906001820390600052602060002001600090919290919091505550600060039080600181540180825580915050906001820390600052602060002001600090919290919091505550600060049080600181540180825580915050906001820390600052602060002001600090919290919091505550600060059080600181540180825580915050906001820390600052602060002001600090919290919091505550610153806101016000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063853255cc14610030575b600080fd5b61003861004e565b6040518082815260200191505060405180910390f35b60007323346584d341c839148cd0b1166a16394074a1746387fbcc7760006040518263ffffffff1660e01b8152600401808060200182810382528381815481526020019150805480156100c057602002820191906000526020600020905b8154815260200190600101908083116100ac575b50509250505060206040518083038186803b1580156100de57600080fd5b505af41580156100f2573d6000803e3d6000fd5b505050506040513d602081101561010857600080fd5b810190808051906020019092919050505090509056fea265627a7a72315820971387e8880e897ea84556392fddbf14557ac01fec2b059cec87e9e436b79e2f64736f6c634300050d0032' + +abi = [{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"constant":true,"inputs":[],"name":"sum","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}] +tx = contract_deploy(bytecode, from_address) +print(tx) +tx_receipt = platon.waitForTransactionReceipt(tx) +print(tx_receipt) +contractAddress = tx_receipt.contractAddress +print(contractAddress) + + +# hrpgot, data = bech32.decode("lax", from_address) +# address = to_checksum_address(bytes(data)) +# print('qqq') +# print(address) + +def SendTxn(txn): + signed_txn = platon.account.signTransaction(txn,private_key=send_privatekey) + res = platon.sendRawTransaction(signed_txn.rawTransaction).hex() + txn_receipt = platon.waitForTransactionReceipt(res) + print(res) + return txn_receipt + + + +contract_instance = platon.contract(address=contractAddress, abi=abi) + +# txn = contract_instance.functions.ifControl(20).buildTransaction( +# { +# 'chainId':102, +# 'nonce':platon.getTransactionCount(from_address), +# 'gas':1000000, +# 'value':0, +# 'gasPrice':1000000000, +# } +# ) +# print(SendTxn(txn)) + + +result = contract_instance.functions.sum().call() +print(result) \ No newline at end of file diff --git a/tests/evmevent.py b/tests/evmevent.py new file mode 100644 index 0000000..383283f --- /dev/null +++ b/tests/evmevent.py @@ -0,0 +1,46 @@ +from client_sdk_python import Web3,HTTPProvider +from client_sdk_python.eth import PlatON + +true = True +false = False + +w3 = Web3(HTTPProvider("http://10.1.1.2:6789")) +platon = PlatON(w3) +print(w3.isConnected()) + +from_address = "lax1uqug0zq7rcxddndleq4ux2ft3tv6dqljphydrl" +print(from_address) + +send_privatekey = "983759fe9aac227c535b21d78792d79c2f399b1d43db46ae6d50a33875301557" + +bytecode = '608060405234801561001057600080fd5b50610169806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806301ad4d8714610046578063477a5c981461006a578063edd89c081461008e575b600080fd5b61004e6100bf565b604051808260ff1660ff16815260200191505060405180910390f35b6100726100d1565b604051808260ff1660ff16815260200191505060405180910390f35b6100bd600480360360208110156100a457600080fd5b81019080803560ff1690602001909291905050506100e7565b005b6000809054906101000a900460ff1681565b60008060009054906101000a900460ff16905090565b806000806101000a81548160ff021916908360ff1602179055508060ff167f6c2b4666ba8da5a95717621d879a77de725f3d816709b9cbe9f059b8f875e28460405160405180910390a25056fea265627a7a7231582090ef2e55c9c3e1fc6cc130590605b1904b7c91f07bf401c7463c6dcebe70a96e64736f6c634300050c0032' + +abi = [{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_var","type":"uint256"}],"name":"MyEvent","type":"event"},{"constant":true,"inputs":[],"name":"_myVar","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint8","name":"_var","type":"uint8"}],"name":"setVar","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getVar","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"}] + +Payable = platon.contract(abi=abi, bytecode=bytecode) + +tx_hash = Payable.constructor().transact( + { + 'from':from_address, + 'gas':1500000, + } +) + +# Wait for the transaction to be mined, and get the transaction receipt +tx_receipt = platon.waitForTransactionReceipt(tx_hash) + +# Create the contract instance with the newly-deployed address +greeter = platon.contract(address=tx_receipt.contractAddress, abi=abi) + +tx_hash = greeter.functions.setVar(100).transact( + { + 'from':from_address, + 'gas':1500000, + } +) + +tx_receipt = platon.waitForTransactionReceipt(tx_hash) +print(tx_receipt) + +topic_param = greeter.events.MyEvent().processReceipt(tx_receipt) +print(topic_param) \ No newline at end of file diff --git a/tests/generate_go_ethereum_fixture.py b/tests/generate_go_ethereum_fixture.py index cc8881f..91aa628 100644 --- a/tests/generate_go_ethereum_fixture.py +++ b/tests/generate_go_ethereum_fixture.py @@ -10,7 +10,7 @@ import tempfile import time -from eth_utils.curried import ( +from client_sdk_python.packages.eth_utils.curried import ( apply_formatter_if, is_bytes, is_checksum_address, diff --git a/tests/get_address_hrp_test.py b/tests/get_address_hrp_test.py new file mode 100644 index 0000000..94f1b13 --- /dev/null +++ b/tests/get_address_hrp_test.py @@ -0,0 +1,25 @@ +from client_sdk_python import Web3, HTTPProvider +from client_sdk_python.eth import PlatON +from client_sdk_python.ppos import Ppos +from client_sdk_python.pip import Pip + + +def unit_test_address(url): + w3 = Web3(HTTPProvider(url)) + platon = PlatON(w3) + print(platon.net_type) + ppos = Ppos(w3) + pip = Pip(w3) + print(ppos.getPackageReward()) + print('w3 net_type is:{}'.format(platon.net_type)) + print('platon net_type is:{}'.format(platon.net_type)) + print('stakingAddress is:{}'.format(ppos.stakingAddress)) + print('penaltyAddress is:{}'.format(ppos.penaltyAddress)) + print('delegateRewardAddress is:{}'.format(ppos.delegateRewardAddress)) + print('restrictingAddress is:{}'.format(ppos.restrictingAddress)) + print('pipAddress is:{}'.format(pip.pipAddress)) + + +if __name__ == '__main__': + test_url = "http://127.0.0.1:6789" + unit_test_address(test_url) diff --git a/tests/integration/generate_fixtures/common.py b/tests/integration/generate_fixtures/common.py index 7d305e8..5d848d8 100644 --- a/tests/integration/generate_fixtures/common.py +++ b/tests/integration/generate_fixtures/common.py @@ -7,7 +7,7 @@ import tempfile import time -from eth_utils import ( +from client_sdk_python.packages.eth_utils import ( is_checksum_address, to_text, ) diff --git a/tests/integration/generate_fixtures/go_ethereum.py b/tests/integration/generate_fixtures/go_ethereum.py index c9a1924..1d9cb55 100644 --- a/tests/integration/generate_fixtures/go_ethereum.py +++ b/tests/integration/generate_fixtures/go_ethereum.py @@ -5,7 +5,7 @@ import shutil import sys -from eth_utils import ( +from client_sdk_python.packages.eth_utils import ( is_dict, is_same_address, ) diff --git a/tests/integration/generate_fixtures/parity.py b/tests/integration/generate_fixtures/parity.py index 498a725..675cace 100644 --- a/tests/integration/generate_fixtures/parity.py +++ b/tests/integration/generate_fixtures/parity.py @@ -6,7 +6,7 @@ import sys import time -from eth_utils import ( +from client_sdk_python.packages.eth_utils import ( to_text, ) diff --git a/tests/integration/go_ethereum/conftest.py b/tests/integration/go_ethereum/conftest.py index 334222a..ba3ab34 100644 --- a/tests/integration/go_ethereum/conftest.py +++ b/tests/integration/go_ethereum/conftest.py @@ -4,7 +4,7 @@ import shutil import subprocess -from eth_utils import ( +from client_sdk_python.packages.eth_utils import ( is_checksum_address, is_dict, to_text, diff --git a/tests/integration/parity/conftest.py b/tests/integration/parity/conftest.py index 8db497b..b7ed10a 100644 --- a/tests/integration/parity/conftest.py +++ b/tests/integration/parity/conftest.py @@ -3,7 +3,7 @@ import shutil import tempfile -from eth_utils import ( +from client_sdk_python.packages.eth_utils import ( is_checksum_address, is_dict, ) diff --git a/tests/integration/parity/install_parity.py b/tests/integration/parity/install_parity.py index 852d1a4..66c3939 100644 --- a/tests/integration/parity/install_parity.py +++ b/tests/integration/parity/install_parity.py @@ -6,7 +6,7 @@ import stat import sys -from eth_utils import ( +from client_sdk_python.packages.eth_utils import ( to_tuple, ) import requests diff --git a/tests/integration/parity/utils.py b/tests/integration/parity/utils.py index 0403533..c4e5c8a 100644 --- a/tests/integration/parity/utils.py +++ b/tests/integration/parity/utils.py @@ -3,7 +3,7 @@ import subprocess import time -from eth_utils import ( +from client_sdk_python.packages.eth_utils import ( to_text, ) import requests diff --git a/tests/integration/test_ethereum_tester.py b/tests/integration/test_ethereum_tester.py index 486474a..6c4096b 100644 --- a/tests/integration/test_ethereum_tester.py +++ b/tests/integration/test_ethereum_tester.py @@ -4,7 +4,7 @@ from eth_tester import ( EthereumTester, ) -from eth_utils import ( +from client_sdk_python.packages.eth_utils import ( is_checksum_address, is_dict, ) diff --git a/tests/newwasm_event.py b/tests/newwasm_event.py new file mode 100644 index 0000000..7b56669 --- /dev/null +++ b/tests/newwasm_event.py @@ -0,0 +1,91 @@ +from client_sdk_python import Web3,HTTPProvider +from client_sdk_python.eth import PlatON + +true = True +false = False +# import binascii +# f = open('D:/juzhen/new contract/JS_wasmtest1.wasm','rb') +# contents=f.read() +# bytecode=binascii.b2a_hex(contents) +# print(bytecode) + +# w3 = Web3(HTTPProvider("http://10.1.1.5:6789")) +# platon = PlatON(w3) +# print(w3.isConnected()) +# +# from_address = "lax1yjjzvjph3tw4h2quw6mse25y492xy7fzwdtqja" +# print(from_address) +# +# send_privatekey = "b7a7372e78160f71a1a75e03c4aa72705806a05cf14ef39c87fdee93d108588c" + +# bytecode = '608060405234801561001057600080fd5b50610169806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806301ad4d8714610046578063477a5c981461006a578063edd89c081461008e575b600080fd5b61004e6100bf565b604051808260ff1660ff16815260200191505060405180910390f35b6100726100d1565b604051808260ff1660ff16815260200191505060405180910390f35b6100bd600480360360208110156100a457600080fd5b81019080803560ff1690602001909291905050506100e7565b005b6000809054906101000a900460ff1681565b60008060009054906101000a900460ff16905090565b806000806101000a81548160ff021916908360ff1602179055508060ff167f6c2b4666ba8da5a95717621d879a77de725f3d816709b9cbe9f059b8f875e28460405160405180910390a25056fea265627a7a7231582090ef2e55c9c3e1fc6cc130590605b1904b7c91f07bf401c7463c6dcebe70a96e64736f6c634300050c0032' +# +# abi = [{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_var","type":"uint256"}],"name":"MyEvent","type":"event"},{"constant":true,"inputs":[],"name":"_myVar","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint8","name":"_var","type":"uint8"}],"name":"setVar","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getVar","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"}] + +w3 = Web3(HTTPProvider("http://10.1.1.2:6789")) +platon = PlatON(w3) +print(w3.isConnected()) + +from_address = "lax1uqug0zq7rcxddndleq4ux2ft3tv6dqljphydrl" +print(from_address) + +send_privatekey = "983759fe9aac227c535b21d78792d79c2f399b1d43db46ae6d50a33875301557" + +bytecode='0061736d0100000001681260027f7f0060017f017f60027f7f017f60017f0060037f7f7f0060037f7f7f017f60000060047f7f7f7f0060047f7f7f7f017f60027f7e0060017f017e60037f7e7e0060037f7e7e017f60017e017f60057f7f7f7f7f0060037e7e7f006000017f60027e7e017f02ce020f03656e760c706c61746f6e5f70616e6963000603656e760b706c61746f6e5f73686133000703656e760d726c705f6c6973745f73697a65000103656e760f706c61746f6e5f726c705f6c697374000403656e760e726c705f62797465735f73697a65000203656e7610706c61746f6e5f726c705f6279746573000403656e760d726c705f753132385f73697a65001103656e760f706c61746f6e5f726c705f75313238000f03656e7617706c61746f6e5f6765745f696e7075745f6c656e677468001003656e7610706c61746f6e5f6765745f696e707574000303656e7617706c61746f6e5f6765745f73746174655f6c656e677468000203656e7610706c61746f6e5f6765745f7374617465000803656e7610706c61746f6e5f7365745f7374617465000703656e760c706c61746f6e5f6576656e74000703656e760d706c61746f6e5f72657475726e000003c701c5010600020200050000010202020302020400000e0000000200010002000100020000010207000200020002000002050000020101020504070003030105000405020404000001050204030001050c00050b01000005080305000106060605040a0a030103010101010101010d0901000100000003000100020100010001010001010a0d0900010000010000020100010001000100000100000100030100000108030100020100090001030100010100000c0b02080003000000030301040604010102070003000405017001050505030100020608017f0141908c040b073904066d656d6f72790200115f5f7761736d5f63616c6c5f63746f7273000f0f5f5f66756e63735f6f6e5f65786974006a06696e766f6b650068090a010041010b0426272a2b0a97b602c501050010cb010baa0301097f230041c0016b22022400200241b90810112104200241e8006a410210122103200241d8006a20041013200241c8006a20001013200241406b4100360200200241386a4200370300200241306a420037030020024200370328200241286a20022802582204200228025c101420022802482205200228024c101421062003200228022810152003200241d8006a10162003200241c8006a1016200328020c200341106a28020047044010000b2003280204210720032802002108200241106a1017210020024180016a200110182101200241a8016a4100360200200241a0016a420037030020024198016a4200370300200242003703900120024190016a41001019200241b0016a20011018101a410110192109200228029001210a200941046a101b2000200a101520004101101c20024190016a20011018101d220028020c200041106a28020047044010000b2008200720002802002000280204100d200028020c22010440200020013602100b200641046a101b200504402002200536024c0b200404402002200436025c0b200328020c22000440200320003602100b200241c0016a24000b910101027f20004200370200200041086a410036020020012102024003402002410371044020022d0000450d02200241016a21020c010b0b2002417c6a21020340200241046a22022802002203417f73200341fffdfb776a7141808182847871450d000b0340200341ff0171450d01200241016a2d00002103200241016a21020c000b000b20002001200220016b105620000b1d0020001057200041146a41003602002000420037020c20002001101c0ba40201047f230041206b2202240020024100360218200242003703100240027f4100200128020420012d00002204410176200441017122051b2204450d001a2001280208200141016a20051b2103200241106a2004104b0340200404402002280214220120032d00003a00002002200141016a3602142004417f6a2104200341016a21030c010b0b2002280210210320022802140b220420036b41204d044020002004360204200020033602002000200228021836020820024100360218200242003703100c010b20024100360208200242003703002002412010582003200228021420036b200228020022042002280204220120046b10012000200136020420002004360200200020022802083602082003450d00200220033602140b200241206a24000b8b0101017f024020012002460440410121030c010b4101210302400240200220016b2202410146044020012c0000417f4c0d010c030b200241374b0d010b200241016a21030c010b2002105920026a41016a21030b027f200041186a28020022010440200041086a280200200041146a2802002001105a0c010b20000b2201200128020020036a36020020000b13002000280208200149044020002001105c0b0b1600200020012802002200200128020420006b105d1a0b190020001057200041146a41003602002000420037020c20000b4d01017f20004200370200200041086a2202410036020020012d0000410171450440200020012902003702002002200141086a28020036020020000f0b200020012802082001280204105620000bc30c02077f027e230041306b22042400200041046a2107027f20014101460440200041086a280200200041146a280200200041186a22022802002203105a280200210120022003417f6a3602002007105f4180104f044020072000410c6a280200417c6a10600b200141384f047f2001105920016a0520010b41016a2102200041186a28020022010440200041086a280200200041146a2802002001105a0c020b20000c010b02402007105f0d00200041146a28020022014180084f0440200020014180786a360214200041086a2201280200220228020021032001200241046a360200200420033602182007200441186a10610c010b2000410c6a2802002202200041086a2802006b4102752203200041106a2205280200220620002802046b220141027549044041802010402105200220064704400240200028020c220120002802102202470d0020002802082203200028020422064b04402000200320012003200320066b41027541016a417e6d41027422026a1062220136020c2000200028020820026a3602080c010b200441186a200220066b2201410175410120011b22012001410276200041106a10632102200028020c210320002802082101034020012003470440200228020820012802003602002002200228020841046a360208200141046a21010c010b0b200029020421092000200229020037020420022009370200200029020c21092000200229020837020c2002200937020820021064200028020c21010b200120053602002000200028020c41046a36020c0c020b02402000280208220120002802042202470d00200028020c2203200028021022064904402000200120032003200620036b41027541016a41026d41027422026a106522013602082000200028020c20026a36020c0c010b200441186a200620026b2201410175410120011b2201200141036a410276200041106a10632102200028020c210320002802082101034020012003470440200228020820012802003602002002200228020841046a360208200141046a21010c010b0b200029020421092000200229020037020420022009370200200029020c21092000200229020837020c2002200937020820021064200028020821010b2001417c6a2005360200200020002802082201417c6a22023602082002280200210220002001360208200420023602182007200441186a10610c010b20042001410175410120011b200320051063210241802010402106024020022802082201200228020c2203470d0020022802042205200228020022084b04402002200520012005200520086b41027541016a417e6d41027422036a106222013602082002200228020420036a3602040c010b200441186a200320086b2201410175410120011b22012001410276200241106a280200106321032002280208210520022802042101034020012005470440200328020820012802003602002003200328020841046a360208200141046a21010c010b0b20022902002109200220032902003702002003200937020020022902082109200220032902083702082003200937020820031064200228020821010b200120063602002002200228020841046a360208200028020c2105034020002802082005460440200028020421012000200228020036020420022001360200200228020421012002200536020420002001360208200029020c21092000200229020837020c2002200937020820021064052005417c6a210502402002280204220120022802002203470d0020022802082206200228020c22084904402002200120062006200820066b41027541016a41026d41027422036a106522013602042002200228020820036a3602080c010b200441186a200820036b2201410175410120011b2201200141036a4102762002280210106321062002280208210320022802042101034020012003470440200428022020012802003602002004200428022041046a360220200141046a21010c010b0b20022902002109200220042903183702002002290208210a20022004290320370208200420093703182004200a37032020061064200228020421010b2001417c6a200528020036020020022002280204417c6a3602040c010b0b0b200441186a20071066200428021c410036020041012102200041186a0b2201200128020020026a360200200441306a240020000ba10101037f41012103024002400240200128020420012d00002202410176200241017122041b220241014d0440200241016b0d032001280208200141016a20041b2c0000417f4c0d010c030b200241374b0d010b200241016a21030c010b2002105920026a41016a21030b027f200041186a28020022010440200041086a280200200041146a2802002001105a0c010b20000b2201200128020020036a36020020000bea0101047f230041106b22042400200028020422012000280210220241087641fcffff07716a2103027f410020012000280208460d001a2003280200200241ff07714102746a0b2101200441086a20001066200428020c210203400240200120024604402000410036021420002802082103200028020421010340200320016b41027522024103490d022000200141046a22013602040c000b000b200141046a220120032802006b418020470d0120032802042101200341046a21030c010b0b2002417f6a220241014d04402000418004418008200241016b1b3602100b200020011060200441106a24000b9f0201057f2001044020002802042105200041106a2802002202200041146a280200220349044020022001ad2005ad422086843702002000200028021041086a36021020000f0b027f41002002200028020c22046b410375220641016a2202200320046b2203410275220420042002491b41ffffffff01200341037541ffffffff00491b2204450d001a200441037410400b2102200220064103746a22032001ad2005ad4220868437020020032000280210200028020c22066b22016b2105200220044103746a2102200341086a2103200141014e0440200520062001103c1a0b20002002360214200020033602102000200536020c20000f0b200041001002200028020422016a10d30141004100200120002802006a1003200010d20120000b2c01017f20002001280208200141016a20012d0000220041017122021b2001280204200041017620021b105d0bc80301087f230041c0016b22032400200341ac0810112105200341e8006a410210122104200341d8006a20051013200341c8006a20001013200341406b4100360200200341386a4200370300200341306a420037030020034200370328200341286a20032802582205200328025c101420032802482206200328024c101421072004200328022810152004200341d8006a10162004200341c8006a1016200428020c200441106a28020047044010000b2004280204210820042802002109200341106a1017210020034180016a200110182101200320023b018c01200341a8016a4100360200200341a0016a420037030020034198016a4200370300200342003703900120034190016a41001019200341b0016a20011018101a220220032f018c01101f2002410110192102200328029001210a200241046a101b2000200a101520004102101c20034190016a20011018101d220020032f018c011020200028020c200041106a28020047044010000b2009200820002802002000280204100d200028020c22010440200020013602100b200741046a101b200604402003200636024c0b200504402003200536025c0b200428020c22000440200420003602100b200341c0016a24000b0c0020002001ad4200105b1a0b0b0020002001ad4200105e0bf20301067f230041d0016b22052400200541086a419f0810112107200541f0006a410310122106200541e0006a20071013200541d0006a20001013200541c8006a4100360200200541406b4200370300200541386a420037030020054200370330200541306a2005280260220020052802641014200528025022072005280254101422082001101f2006200528023010152006200541e0006a10162006200541d0006a1016200620011020200628020c200641106a28020047044010000b200628020421092006280200210a200541186a1017210120054188016a20021018210220052004360298012005200336029401200541b8016a4100360200200541b0016a4200370300200541a8016a4200370300200542003703a001200541a0016a41001019200541c0016a20021018101a2203200528029401101f2003200528029801101f200341011019210320052802a0012104200341046a101b20012004101520014103101c200541a0016a20021018101d2201200528029401102020012005280298011020200128020c200141106a28020047044010000b200a200920012802002001280204100d200128020c22020440200120023602100b200841046a101b20070440200520073602540b20000440200520003602640b200628020c22010440200620013602100b200541d0016a24000b2e01017f230041206b22022400200241106a418d081011200241990810111010200020013a0010200241206a24000b3301017f230041206b22022400200241106a4180081011200241870810112001101e200041286a20013b0100200241206a24000b3701017f230041206b22022400200241106a4180081011200120024187081011200120011021200041406b2001360200200241206a24000b930201047f20002001470440200128020420012d00002202410176200241017122041b2102200141016a210320012802082105410a21012005200320041b210420002d0000410171220304402000280200417e71417f6a21010b200220014d0440027f2003044020002802080c010b200041016a0b210120020440200120042002104f0b200120026a41003a000020002d000041017104402000200236020420000f0b200020024101743a000020000f0b416f2103200141e6ffffff074d0440410b20014101742201200220022001491b220141106a4170712001410b491b21030b2003104022012004200210cc01200020023602042000200341017236020020002001360208200120026a41003a00000b20000b0d00200041b0016a20013a00000b0b00200041b0016a2c00000b23002000200110251a2000410c6a2001410c6a10251a200041186a200141186a10251a0b25002000200110181a2000410c6a2001410c6a10181a200041186a200141186a10181a20000b0d00200041c8026a20013a00000b0b00200041c8026a2c00000b9e0101047f2000200147044020012802042203200128020022026b41017522042000280208200028020022016b4101754d0440200041046a21052004200028020420016b41017522004b04402002200220004101746a2200200110541a200020032005104c0f0b200520022003200110543602000f0b2001044020004100360208200042003702000b2000200020041055105220022003200041046a104c0b0b3e01017f2000420037020020004100360208200128020420012802006b2202044020002002410175105220012802002001280204200041046a104c0b20000b3001027f200141046a21032001280200210203402002200346044020004188046a2001102f052002103021020c010b0b0be00201067f230041206b22042400024020002001460d00200141046a21062001280200210102402000280208450d00200028020021032000200041046a3602002000410036020820002802042102200041003602042002410036020820032802042202200320021b2102034020022203450d0120012006470440200341106a200141106a102521072003411c6a2001411c6a10251a024020032802082202450440410021020c010b2003200228020022054604402002410036020020022802042205450d012005104921020c010b200241003602042005450d002005104921020b2000200441106a2007104a2107200020042802102007200310452001103021010c010b0b0340200328020822030d000b200621010b034020012006460d01200441106a2000200141106a105020002004410c6a2004280210220341106a104a21022000200428020c2002200310452001103021010c000b000b200441206a24000b3601017f024020002802042201044003402001220028020022010d000c020b000b0340200020002802082200280200470d000b0b20000bd60101067f230041106b22022400200042003702042000200041046a2203360200200141046a21062001280200210103402001200646450440200141106a21050240027f027f0240024020032000280200460440200321040c010b20031041220441106a20051042450d010b20032802004504402002200336020c2003210420030c030b2002200436020c200441046a0c010b20002002410c6a200510430b22042802000d01200228020c0b21072002200020051050200020072004200228020010450b2001103021010c010b0b200241106a240020000b2300200041d0016a200110251a20004198016a20033a0000200041f8026a20023602000b920101047f2000200147044020012802042203200128020022026b22042000280208200028020022016b4d0440200041046a21052004200028020420016b22004b04402002200020026a22002001104d1a200020032005104c0f0b2005200220032001104d3602000f0b2001044020004100360208200042003702000b200020002004104e104b20022003200041046a104c0b0b3b01017f2000420037020020004100360208200128020420012802006b2202044020002002104b20012802002001280204200041046a104c0b20000b2601017f0340200241f800470440200020026a200120026a10251a2002410c6a21020c010b0b0b2301017f0340200020026a200120026a10181a2002410c6a220241f800470d000b20000b13002000200110251a2000200128020c36020c0b15002000200110181a2000200128020c36020c20000b3001027f200141046a210320012802002102034020022003460440200041f8066a2001103a052002103021020c010b0b0bd30201067f230041206b22042400024020002001460d00200141046a21062001280200210102402000280208450d00200028020021032000200041046a3602002000410036020820002802042102200041003602042002410036020820032802042202200320021b2102034020022203450d0120012006470440200341106a200141106a10252107024020032802082202450440410021020c010b2003200228020022054604402002410036020020022802042205450d012005104921020c010b200241003602042005450d002005104921020b2000200441106a2007104a2107200020042802102007200310452001103021010c010b0b0340200328020822030d000b200621010b034020012006460d01200441106a2000200141106a104420002004410c6a2004280210220341106a104a21022000200428020c2002200310452001103021010c000b000b200441206a24000bd60101067f230041106b22022400200042003702042000200041046a2203360200200141046a21062001280200210103402001200646450440200141106a21050240027f027f0240024020032000280200460440200321040c010b20031041220441106a20051042450d010b20032802004504402002200336020c2003210420030c030b2002200436020c200441046a0c010b20002002410c6a200510430b22042802000d01200228020c0b21072002200020051044200020072004200228020010450b2001103021010c010b0b200241106a240020000bfc0801067f03400240200020046a2105200120046a210320022004460d002003410371450d00200520032d00003a0000200441016a21040c010b0b200220046b210602402005410371220745044003402006411049450440200020046a2203200120046a2205290200370200200341086a200541086a290200370200200441106a2104200641706a21060c010b0b027f2006410871450440200120046a2103200020046a0c010b200020046a2205200120046a2204290200370200200441086a2103200541086a0b21042006410471044020042003280200360200200341046a2103200441046a21040b20064102710440200420032f00003b0000200341026a2103200441026a21040b2006410171450d01200420032d00003a000020000f0b024020064120490d002007417f6a220741024b0d00024002400240024002400240200741016b0e020102000b2005200120046a220328020022073a0000200541016a200341016a2f00003b0000200041036a2108200220046b417d6a2106034020064111490d03200420086a2203200120046a220541046a2802002202410874200741187672360200200341046a200541086a2802002207410874200241187672360200200341086a2005410c6a28020022024108742007411876723602002003410c6a200541106a2802002207410874200241187672360200200441106a2104200641706a21060c000b000b2005200120046a220328020022073a0000200541016a200341016a2d00003a0000200041026a2108200220046b417e6a2106034020064112490d03200420086a2203200120046a220541046a2802002202411074200741107672360200200341046a200541086a2802002207411074200241107672360200200341086a2005410c6a28020022024110742007411076723602002003410c6a200541106a2802002207411074200241107672360200200441106a2104200641706a21060c000b000b2005200120046a28020022073a0000200041016a21082004417f7320026a2106034020064113490d03200420086a2203200120046a220541046a2802002202411874200741087672360200200341046a200541086a2802002207411874200241087672360200200341086a2005410c6a28020022024118742007410876723602002003410c6a200541106a2802002207411874200241087672360200200441106a2104200641706a21060c000b000b200120046a41036a2103200020046a41036a21050c020b200120046a41026a2103200020046a41026a21050c010b200120046a41016a2103200020046a41016a21050b20064110710440200520032d00003a00002005200328000136000120052003290005370005200520032f000d3b000d200520032d000f3a000f200541106a2105200341106a21030b2006410871044020052003290000370000200541086a2105200341086a21030b2006410471044020052003280000360000200541046a2105200341046a21030b20064102710440200520032f00003b0000200541026a2105200341026a21030b2006410171450d00200520032d00003a00000b20000b2b01027f200141046a210203402002280200220341046a210220012003470d000b200041a80b6a2001103e0bbe0201057f024020002001460d00200041046a2102200141046a21030340200228020021020240027f4101200328020022032001460d001a20002002470d0141000b210402402000200246044020040d044114104022054100360200200541086a200341086a10181a20052104410121060340200120032802042203460d0241141040220241086a200341086a10181a2002200436020020042002360204200641016a2106200221040c000b000b200228020022032000280200220128020436020420012802042003360200034020002002460d0420002000280208417f6a360208200228020421020c000b000b2000280200220220053602042005200236020020002004360200200420003602042000200028020820066a3602080c020b200241086a200341086a10251a200241046a2102200341046a21030c000b000b0b840101037f200041003602082000200036020420002000360200200141046a2102037f20022802002203200146047f2000054114104022024100360200200241086a200341086a10181a20022000360204200028020021042000200236020020022004360200200420023602042000200028020841016a360208200341046a21020c010b0b0b0b002000410120001b10670b3e01027f024020002802002201044003402001220228020422010d000c020b000b03402000280208220228020020004621012002210020010d000b0b20020bb20101067f02400240200128020420012d00002202410176200241017122031b2205200028020420002d00002202410176200241017122041b2206200520064922071b2202450d002000280208200041016a20041b21002001280208200141016a20031b210103402002450d0120002d0000220320012d00002204460440200141016a2101200041016a21002002417f6a21020c010b0b200320046b22020d010b417f200720062005491b21020b2002411f760b890101027f200041046a2103024020002802042200044002400340024002402002200041106a220410420440200028020022040d012001200036020020000f0b200420021042450d03200041046a210320002802042204450d01200321000b20002103200421000c010b0b2001200036020020030f0b200120003602000c010b200120033602000b20030b2d01017f2000411c104022033602002000200141046a360204200341106a200210181a200041086a41013a00000b480020032001360208200342003702002002200336020020002802002802002201044020002001360200200228020021030b2000280204200310462000200028020841016a3602080bec0101037f200120002001463a000c03400240024020002001460d00200128020822022d000c0d002002200228020822032802002204460440024020032802042204450d0020042d000c0d002004410c6a21010c030b20012002280200470440200210472002280208220228020821030b200241013a000c200341003a000c200310480f0b02402004450d0020042d000c0d002004410c6a21010c020b20012002280200460440200210482002280208220228020821030b200241013a000c200341003a000c200310470b0f0b200241013a000c200320002003463a000c200141013a0000200321010c000b000b5101027f200020002802042201280200220236020420020440200220003602080b200120002802083602082000280208220220022802002000474102746a200136020020002001360208200120003602000b5101027f200020002802002201280204220236020020020440200220003602080b200120002802083602082000280208220220022802002000474102746a200136020020002001360208200120003602040b1d01017f03402000220128020022000d00200128020422000d000b20010b5c01017f0240200028020422030440034002402002200341106a1042044020032802002200450d040c010b200328020422000d0020012003360200200341046a0f0b200021030c000b000b200041046a21030b2001200336020020030b2001017f2000200110402202360200200020023602042000200120026a3602080b2800200120006b220141014e0440200228020020002001103c1a2002200228020020016a3602000b0b1900200120006b22010440200220002001104f0b200120026a0b2e01017f2001200028020820002802006b2200410174220220022001491b41ffffffff07200041ffffffff03491b0b8d0301037f024020002001460d00200120006b20026b410020024101746b4d0440200020012002103c1a0c010b20002001734103712103027f024020002001490440200020030d021a410021030340200120036a2105200020036a2204410371450440200220036b210241002103034020024104490d04200320046a200320056a280200360200200341046a21032002417c6a21020c000b000b20022003460d04200420052d00003a0000200341016a21030c000b000b024020030d002001417f6a21040340200020026a22034103714504402001417c6a21032000417c6a2104034020024104490d03200220046a200220036a2802003602002002417c6a21020c000b000b2002450d042003417f6a200220046a2d00003a00002002417f6a21020c000b000b2001417f6a210103402002450d03200020026a417f6a200120026a2d00003a00002002417f6a21020c000b000b200320056a2101200320046a0b210303402002450d01200320012d00003a00002002417f6a2102200341016a2103200141016a21010c000b000b0b2c01017f20004128104022033602002000200141046a360204200341106a20021051200041086a41013a00000b16002000200110181a2000410c6a2001410c6a10181a0b2301017f2000200110532202360200200020023602042000200220014101746a3602080b0900200041017410400b2501017f200120006b2201410175210320010440200220002001104f0b200220034101746a0b2a002001200028020820002802006b220020002001491b41ffffffff07200041017541ffffffff03491b0b5b01027f02402002410a4d0440200020024101743a0000200041016a21030c010b200241106a4170712204104021032000200236020420002004410172360200200020033602080b20032001200210cc01200220036a41003a00000b1600200041003602082000420037020020004100105c0bdd0101047f024020002802042203200028020022026b22042001490440200028020820036b200120046b22024f04400340200341003a00002000200028020441016a22033602042002417f6a22020d000c030b000b20002001104e220104402001104021050b200420056a220421030340200341003a0000200341016a21032002417f6a22020d000b200120056a210520042000280204200028020022046b22016b2102200141014e0440200220042001103c1a0b2000200536020820002003360204200020023602000f0b200420014d0d002000200120026a3602040b0b1e01017f03402000044020004108762100200141016a21010c010b0b20010b25002000200120026a417f6a220241087641fcffff07716a280200200241ff07714102746a0b900101027f4101210420014280015441002002501b450440034020012002845045044020024238862001420888842101200341016a2103200242088821020c010b0b200341384f047f2003105920036a0520030b41016a21040b027f200041186a28020022030440200041086a280200200041146a2802002003105a0c010b20000b2203200328020020046a36020020000b2f01017f200028020820014904402001106720002802002000280204103c210220002001360208200020023602000b0b2c01017f2000200120021004200028020422036a10d30120012002200320002802006a1005200010d20120000b2a01017f2000200220011006200028020422036a10d30120022001200320002802006a1007200010d2010b2801017f200028020820002802046b2201410874417f6a410020011b200028021420002802106a6b0b2501017f200028020821020340200120024645044020002002417c6a22023602080c010b0b0ba10202057f017e230041206b22052400024020002802082202200028020c2203470d0020002802042204200028020022064b04402000200420022004200420066b41027541016a417e6d41027422036a106222023602082000200028020420036a3602040c010b200541086a200320066b2202410175410120021b220220024102762000410c6a10632103200028020821042000280204210203402002200446450440200328020820022802003602002003200328020841046a360208200241046a21020c010b0b20002902002107200020032902003702002003200737020020002902082107200020032902083702082003200737020820031064200028020821020b200220012802003602002000200028020841046a360208200541206a24000b2501017f200120006b2201410275210320010440200220002001104f0b200220034102746a0b4f01017f2000410036020c200041106a2003360200200104402001410274104021040b200020043602002000200420024102746a22023602082000200420014102746a36020c2000200236020420000b2b01027f200028020821012000280204210203402001200247044020002001417c6a22013602080c010b0b0b1b00200120006b22010440200220016b220220002001104f0b20020b4f01037f20012802042203200128021020012802146a220441087641fcffff07716a21022000027f410020032001280208460d001a2002280200200441ff07714102746a0b360204200020023602000b9b0101047f230041106b220124002001200036020c2000047f41880c200041086a2202411076220041880c2802006a220336020041840c41840c280200220420026a41076a417871220236020002400240200341107420024d044041880c200341016a360200200041016a21000c010b2000450d010b200040000d0010000b20042001410c6a4104103c41086a0541000b2100200141106a240020000b090010cb011069106a0be82602057f027e230041c0166b2201240010082200106722021009200141d00a6a200141086a20022000106b22004100106c02400240200141d00a6a106d2205500d0041c208106e20055104402000106f200141d00a6a107010710c020b41c708106e200551044020001072410247044010000b200141d00a6a20004101106c200141d00a6a10732100200141d00a6a1070220220001022200210710c020b41d008106e20055104402000106f200141d00a6a107022032d00102102200141b8086a10172200200210741015200020021020200028020c200041106a28020047044010000b20002802002000280204100e200028020c22020440200020023602100b200310710c020b41d908106e200551044020001072410247044010000b200141d00a6a20004101106c200141d00a6a10752100200141d00a6a1070220220001023200210710c020b41e308106e20055104402000106f200141d00a6a1070220341286a2f01002102200141b8086a10172200200210761015200020021020200028020c200041106a28020047044010000b20002802002000280204100e200028020c22020440200020023602100b200310710c020b41ed08106e200551044020001072410247044010000b200141d00a6a20004101106c200141d00a6a10772100200141d00a6a1070220220001024200210710c020b41f708106e20055104402000106f200141d00a6a1070220341406b2802002102200141b8086a10172200200210781015200020021020200028020c200041106a28020047044010000b20002802002000280204100e200028020c22020440200020023602100b200310710c020b418109106e200551044020001072410247044010000b200141d00a6a20004101106c200141d00a6a106d2105200141d00a6a1070220041d8006a2005370300200010710c020b418b09106e20055104402000106f200141d00a6a1070220241d8006a2903002105200141b8086a1017220020051079101520002005107a200028020c200041106a28020047044010000b20002802002000280204100e200028020c22030440200020033602100b200210710c020b419509106e2005510440200141b8066a107b210220001072410247044010000b200141d00a6a20004101106c200141d00a6a2002107c200141d00a6a1070220041f8006a200141b8086a2002101810251a200010710c020b419f09106e20055104402000106f200141a0046a200141d00a6a1070220241f8006a10182100200141b8086a101722032000107d10152003200141b8066a20001018101d220028020c200041106a28020047044010000b20002802002000280204100e200028020c22030440200020033602100b200210710c020b41a909106e2005510440200141003a00b80820001072410247044010000b200141d00a6a20004101106c200141d00a6a200141b8086a107e200141d00a6a107022004198016a20012d00b8083a0000200010710c020b41b109106e20055104402000106f200141d00a6a107022034198016a2d00002102200141b8086a10172200200210741015200020021020200028020c200041106a28020047044010000b20002802002000280204100e200028020c22020440200020023602100b200310710c020b41b909106e200551044020004101107f0c020b41c109106e2005510440200041021080010c020b41c909106e2005510440200141b8066a10810120001072410247044010000b200141d00a6a20004101106c200141d00a6a200141b8066a108201200141d00a6a1070220041d0016a200141b8086a200141b8066a101810251a200010710c020b41d409106e20055104402000106f200141b8066a200141d00a6a1070220241d0016a10181a200141b8086a10172200200141b8066a10830110152000200141b8066a108401200028020c200041106a28020047044010000b20002802002000280204100e200028020c22030440200020033602100b200210710c020b41df09106e2005510440200141b8066a41241085011a200141b8066a108601210220001072410247044010000b200141d00a6a20004101106c200141d00a6a2002108701200141d00a6a107022004190026a200141b8086a200210291028200010710c020b41ec09106e20055104402000106f200141b8086a200141d00a6a107022034190026a10292102200141b8066a101722002002108801101520002002108901200028020c200041106a28020047044010000b20002802002000280204100e200028020c22020440200020023602100b200310710c020b41f909106e200551044020004103107f0c020b41810a106e2005510440200041041080010c020b41890a106e200551044020001072410247044010000b200141d00a6a20004101106c200141d00a6a108a012100200141d00a6a1070220241e0026a20003b0100200210710c020b41920a106e20055104402000106f200141d00a6a1070220341e0026a2e01002102200141b8086a101722002002108b01101520002002108c01200028020c200041106a28020047044010000b20002802002000280204100e200028020c22020440200020023602100b200310710c020b419b0a106e200551044020001072410247044010000b200141d00a6a20004101106c200141d00a6a108d012100200141d00a6a1070220241f8026a2000360200200210710c020b41a40a106e20055104402000106f200141d00a6a1070220341f8026a2802002102200141b8086a101722002002108e01101520002002108c01200028020c200041106a28020047044010000b20002802002000280204100e200028020c22020440200020023602100b200310710c020b41ad0a106e200551044020001072410247044010000b200141d00a6a20004101106c200141d00a6a108f012105200141d00a6a107022004190036a2005370300200010710c020b41b60a106e20055104402000106f200141d00a6a107022024190036a2903002105200141b8086a101722002005109001101520002005109101200028020c200041106a28020047044010000b20002802002000280204100e200028020c22030440200020033602100b200210710c020b41bf0a106e2005510440200141003602c006200142003703b80620001072410247044010000b200141d00a6a20004101106c200141d00a6a200141b8066a109201200141d00a6a1070220241e0036a200141b8086a200141b8066a102d2200102c200028020022030440200020033602040b2002107120012802b8062200450d02200120003602bc060c020b41c90a106e20055104402000106f200141b8066a200141d00a6a1070220341e0036a102d2102200141b8086a101722002002109301101520002002109401200028020c200041106a28020047044010000b20002802002000280204100e200028020c22040440200020043602100b200228020022000440200220003602040b200310710c020b41d30a106e2005510440200142003702bc062001200141b8066a4104723602b80620001072410247044010000b200141d00a6a20004101106c200141d00a6a200141b8066a109501200141d00a6a10702200200141b8086a200141b8066a1031102e200010710c020b41da0a106e20055104402000106f200141b8066a200141d00a6a107022034188046a10312102200141b8086a101722002002109601101520002002109701200028020c200041106a28020047044010000b20002802002000280204100e200028020c22020440200020023602100b200310710c020b41e10a106e2005510440200141b8086a108101200141003a00c808200141003602c408200141c8086a210220001072410447044010000b200141d00a6a20004101106c200141d00a6a200141b8086a108201200141d00a6a20004102106c2001200141d00a6a108d013602c408200141d00a6a20004103106c200141d00a6a2002107e200141d00a6a10702100200141b8066a200141b8086a10181a2000200141b8066a20012802c40820012d00c8081032200010710c020b41f10a106e2005510440200141003602a804200142003703a00420001072410247044010000b200141d00a6a20004101106c200141d00a6a200141a0046a109801200141d00a6a1070220341b0046a200141b8086a200141b8066a200141a0046a10342200103422021033200228020022040440200220043602040b200028020022020440200020023602040b2003107120012802a0042200450d02200120003602a4040c020b41fa0a106e20055104402000106f200141b8066a200141d00a6a1070220341b0046a10342102200141b8086a10172200200228020020022802041099011015200020021016200028020c200041106a28020047044010000b20002802002000280204100e200028020c22040440200020043602100b200228020022000440200220003602040b200310710c020b41830b106e2005510440200141b8066a41f8001085011a200141b8066a109a01210220001072410247044010000b200141d00a6a20004101106c200141d00a6a2002109b01200141d00a6a1070220041c0056a200141b8086a200210361035200010710c020b418c0b106e20055104402000106f200141b8086a200141d00a6a1070220341c0056a10362102200141b8066a101722002002109c01101520002002109d01200028020c200041106a28020047044010000b20002802002000280204100e200028020c22020440200020023602100b200310710c020b41950b106e2005510440200141b8066a109e01210220001072410247044010000b200141d00a6a20004101106c200141d00a6a2002109f01200141d00a6a1070220041d0066a200141b8086a200210381037200010710c020b419d0b106e20055104402000106f200141b8066a200141d00a6a1070220341d0066a10382102200141b8086a10172200200210a00110152000200210a101200028020c200041106a28020047044010000b20002802002000280204100e200028020c22020440200020023602100b200310710c020b41a50b106e2005510440200142003702bc062001200141b8066a4104723602b80620001072410247044010000b200141d00a6a20004101106c200141d00a6a200141b8066a10a201200141d00a6a10702200200141b8086a200141b8066a103b1039200010710c020b41ac0b106e20055104402000106f200141b8066a200141d00a6a1070220341f8066a103b2102200141b8086a10172200200210a30110152000200210a401200028020c200041106a28020047044010000b20002802002000280204100e200028020c22020440200020023602100b200310710c020b41b30b106e2005510440200141b8066a4180021085011a20001072410247044010000b200141d00a6a20004101106c200141d00a6a200141b8066a10a501200141d00a6a10702100200141206a200141b8066a418002103c1a200141b8086a200141206a418002103c1a20004190096a200141b8086a418002103c1a200010710c020b41c00b106e20055104402000106f200141a0026a200141d00a6a107022024190096a418002103c1a200141a0066a10172200200141a0026a10a6011015200141a0046a200141a0026a418002103c1a200141b8066a200141a0046a418002103c1a200141206a200141b8066a418002103c1a200141b8086a200141206a418002103c1a2000200141b8086a418002105d220028020c200041106a28020047044010000b20002802002000280204100e200028020c22030440200020033602100b200210710c020b41cd0b106e2005510440200141003602c0062001200141b8066a3602bc062001200141b8066a3602b80620001072410247044010000b200141d00a6a20004101106c200141d00a6a200141b8066a10a701200141d00a6a10702200200141b8086a200141b8066a103f2202103d200210a80120001071200141b8066a10a8010c020b41d50b106e20055104402000106f200141b8066a200141d00a6a1070220341a80b6a103f2102200141b8086a10172200200210a90110152000200210aa01200028020c200041106a28020047044010000b20002802002000280204100e200028020c22040440200020043602100b200210a801200310710c020b41dd0b106e2005510440200141c8086a22024100360200200141c0086a22034200370300200142003703b80820001072410247044010000b200141d00a6a20004101106c200141d00a6a200141b8086a10ab01200141d00a6a10702100200141b0066a20022802002202360200200141a8066a20032903002205370300200120012903b80822063703a006200041d80b6a2006370300200041e00b6a2005370300200041e80b6a2002360200200010710c020b41e80b106e2005520d002000106f200141306a2200200141d00a6a1070220241e80b6a280000360200200141286a2203200241e00b6a2900003703002001200241d80b6a290000370320200141b8086a10172204200141206a10ac011015200141b0026a20002802002200360200200141a8026a200329030022053703002001200129032022063703a002200141a8046a2005370300200141b0046a2000360200200141a8066a2005370300200141b0066a2000360200200120063703a004200120063703a006200141c8066a2000360200200141c0066a2005370300200120063703b8062004200141b8066a4114105d220028020c200041106a28020047044010000b20002802002000280204100e200028020c22030440200020033602100b200210710c010b10000b200141c0166a24000b880101037f41f40b410136020041f80b2802002100034020000440034041fc0b41fc0b2802002201417f6a2202360200200141014845044041f40b4100360200200020024102746a22004184016a280200200041046a28020011030041f40b410136020041f80b28020021000c010b0b41fc0b412036020041f80b200028020022003602000c010b0b0b0d00200020012002411c10ad010bd00202067f017e230041106b220324002001280208220520024b0440200341086a200110d10120012003280208200328020c10cf0136020c2003200110d101410021052001027f410020032802002207450d001a410020032802042208200128020c2206490d001a200820062006417f461b210420070b360210200141146a2004360200200141003602080b200141106a210603402001280214210402402005200249044020040d01410021040b200020062802002004411410ad011a200341106a24000f0b2003200110d10141002104027f410020032802002205450d001a410020032802042208200128020c2207490d001a200820076b2104200520076a0b210520012004360214200120053602102003200641002005200410cf0110d0012001200329030022093702102001200128020c2009422088a76a36020c2001200128020841016a22053602080c000b000b880102027f017e230041106b22012400200010ae0102400240200010af01450d002000280204450d0020002802002d000041c001490d010b10000b200141086a200010b001200128020c220041094f044010000b200128020821020340200004402000417f6a210020023100002003420886842103200241016a21020c010b0b200141106a240020030b3901027e42a5c688a1c89ca7f94b210103402000300000220250450440200041016a2100200142b383808080207e20028521010c010b0b20010b0e0020001072410147044010000b0bf42901097f230041406a22012400200042ddbe888dc5fcfca4987f370308200041003a0000200141286a101722032000290308107a200328020c200341106a28020047044010000b02402003280200220720032802042208100a2205450d002001410036022020014200370318200141186a200510582007200820012802182202200128021c220620026b100b417f47044020002001200241016a20062002417f736a106b10733a0010200521040b2002450d002001200236021c0b200328020c22020440200320023602100b2004450440200020002d00003a00100b41002104200041003b0118200041206a220242debe888dc5fcfca4987f370300200141286a101722032002290300107a200328020c200341106a28020047044010000b02402003280200220720032802042208100a2205450d002001410036022020014200370318200141186a200510582007200820012802182202200128021c220620026b100b417f47044020002001200241016a20062002417f736a106b10753b0128200521040b2002450d002001200236021c0b200328020c22020440200320023602100b2004450440200020002f01183b01280b4100210420004100360230200041386a220242dfbe888dc5fcfca4987f370300200141286a101722032002290300107a200328020c200341106a28020047044010000b02402003280200220720032802042208100a2205450d002001410036022020014200370318200141186a200510582007200820012802182202200128021c220620026b100b417f47044020002001200241016a20062002417f736a106b1077360240200521040b2002450d002001200236021c0b200328020c22020440200320023602100b2004450440200020002802303602400b20004200370348200041d0006a220442d9be888dc5fcfca4987f370300200141286a101722032004290300107a200328020c200341106a28020047044010000b02402003280200220720032802042208100a2205450440410021020c010b410021022001410036022020014200370318200141186a200510582007200820012802182204200128021c220620046b100b417f47044020002001200441016a20062004417f736a106b106d370358200521020b2004450d002001200436021c0b200328020c22040440200320043602100b2002450440200020002903483703580b200041e0006a107b2109200041f0006a220442a7cea8ad82a0ff995b370300200041f8006a107b2107200141286a101722032004290300107a200328020c200341106a28020047044010000b02402003280200220820032802042206100a2205450440410021020c010b410021022001410036022020014200370318200141186a200510582008200620012802182204200128021c220620046b100b417f4704402001200441016a20062004417f736a106b2007107c200521020b2004450d002001200436021c0b200328020c22040440200320043602100b20024504402007200910251a0b41002104200041003a00880120004190016a220242f4a2efb3f6e5b8ad03370300200141286a101722032002290300107a200328020c200341106a28020047044010000b02402003280200220720032802042208100a2205450d002001410036022020014200370318200141186a200510582007200820012802182202200128021c220620026b100b417f4704402001200241016a20062002417f736a106b20004198016a107e200521040b2002450d002001200236021c0b200328020c22020440200320023602100b2004450440200020002d0088013a0098010b200041003a00a001200041a8016a220342badda0b2f6c5fa8e033703002003200041b0016a10b101450440200020002d00a0013a00b0010b200042003703b801200041c0016a4100360200200041b8016a107b2109200041c8016a2204428aedabfdf7a698fe29370300200041d0016a2207107b1a200141286a101722032004290300107a200328020c200341106a28020047044010000b02402003280200220820032802042206100a2205450440410021020c010b410021022001410036022020014200370318200141186a200510582008200620012802182204200128021c220620046b100b417f4704402001200441016a20062004417f736a106b2007108201200521020b2004450d002001200436021c0b200328020c22040440200320043602100b20024504402007200910251a0b41002104200041e0016a4124108501108601210920004188026a220242d4b7b1edebf7e3f66a37030020004190026a1086012107200141286a101722032002290300107a200328020c200341106a28020047044010000b02402003280200220820032802042206100a2205450d002001410036022020014200370318200141186a200510582008200620012802182202200128021c220620026b100b417f4704402001200241016a20062002417f736a106b2007108701200521040b2002450d002001200236021c0b200328020c22020440200320023602100b20044504402007200910280b200041003a00b802200041c0026a220342ccacbdb4f8a587a93d3703002003200041c8026a10b101450440200020002d00b8023a00c8020b200041003b01d002200041d8026a220442cfacbdb4f8a587a93d370300200141286a101722032004290300107a200328020c200341106a28020047044010000b02402003280200220720032802042208100a2205450440410021020c010b410021022001410036022020014200370318200141186a200510582007200820012802182204200128021c220620046b100b417f47044020002001200441016a20062004417f736a106b108a013b01e002200521020b2004450d002001200436021c0b200328020c22040440200320043602100b2002450440200020002f01d0023b01e0020b41002104200041003602e802200041f0026a220242ceacbdb4f8a587a93d370300200141286a101722032002290300107a200328020c200341106a28020047044010000b02402003280200220720032802042208100a2205450d002001410036022020014200370318200141186a200510582007200820012802182202200128021c220620026b100b417f47044020002001200241016a20062002417f736a106b108d013602f802200521040b2002450d002001200236021c0b200328020c22020440200320023602100b2004450440200020002802e8023602f8020b200042003703800320004188036a220442c8acbdb4f8a587a93d370300200141286a101722032004290300107a200328020c200341106a28020047044010000b02402003280200220720032802042208100a2205450440410021020c010b410021022001410036022020014200370318200141186a200510582007200820012802182204200128021c220620046b100b417f47044020002001200441016a20062004417f736a106b108f0137039003200521020b2004450d002001200436021c0b200328020c22040440200320043602100b20024504402000200029038003370390030b410021042000410036029803200041a0036a220242e2e780dbeae4fcabe100370300200141286a101722032002290300107a200328020c200341106a28020047044010000b02402003280200220720032802042208100a2205450d002001410036022020014200370318200141186a200510582007200820012802182202200128021c220620026b100b417f47044020002001200241016a20062002417f736a106b10773602a803200521040b2002450d002001200236021c0b200328020c22020440200320023602100b200445044020002000280298033602a8030b200042003703b003200041b8036a220442b3debf9dbddf9ca832370300200141286a101722032004290300107a200328020c200341106a28020047044010000b02402003280200220720032802042208100a2205450440410021020c010b410021022001410036022020014200370318200141186a200510582007200820012802182204200128021c220620046b100b417f47044020002001200441016a20062004417f736a106b106d3703c003200521020b2004450d002001200436021c0b200328020c22040440200320043602100b2002450440200020002903b0033703c0030b200042003702c80341002104200041e8036a4100360200200041e0036a22074200370200200041d8036a2202429fe6c89bc186c5be1d370300200041d0036a4100360200200141286a101722032002290300107a200328020c200341106a28020047044010000b02402003280200220820032802042206100a2205450d002001410036022020014200370318200141186a200510582008200620012802182202200128021c220920026b100b417f4704402001200241016a20092002417f736a106b2007109201200521040b2002450d002001200236021c0b200328020c22020440200320023602100b20044504402007200041c8036a102c0b200041f4036a220342003702002000418c046a2204420037020020004180046a2202428cbcadf0bacdb08975370300200020033602f00320004188046a22072004360200200141286a101722032002290300107a200328020c200341106a28020047044010000b02402003280200220820032802042206100a2205450440410021020c010b410021022001410036022020014200370318200141186a200510582008200620012802182204200128021c220920046b100b417f4704402001200441016a20092004417f736a106b2007109501200521020b2004450d002001200436021c0b200328020c22040440200320043602100b20024504402007200041f0036a102f0b200042003702980441002104200041b8046a4100360200200041b0046a22074200370200200041a8046a220242bd8ce2969cacfba4b07f370300200041a0046a4100360200200141286a101722032002290300107a200328020c200341106a28020047044010000b02402003280200220820032802042206100a2205450d002001410036022020014200370318200141186a200510582008200620012802182202200128021c220920026b100b417f4704402001200241016a20092002417f736a106b2007109801200521040b2002450d002001200236021c0b200328020c22020440200320023602100b2004450440200720004198046a10330b41002104200041c0046a41f800108501109a012109200041b8056a2202429fa88ce0a0829ecea47f370300200041c0056a109a012107200141286a101722032002290300107a200328020c200341106a28020047044010000b02402003280200220820032802042206100a2205450d002001410036022020014200370318200141186a200510582008200620012802182202200128021c220620026b100b417f4704402001200241016a20062002417f736a106b2007109b01200521040b2002450d002001200236021c0b200328020c22020440200320023602100b20044504402007200910350b200041b8066a109e012109200041c8066a220442bcf8d4f484c7a18d807f370300200041d0066a109e012107200141286a101722032004290300107a200328020c200341106a28020047044010000b02402003280200220820032802042206100a2205450440410021020c010b410021022001410036022020014200370318200141186a200510582008200620012802182204200128021c220620046b100b417f4704402001200441016a20062004417f736a106b2007109f01200521020b2004450d002001200436021c0b200328020c22040440200320043602100b20024504402007200910370b200041e4066a22034200370200200041fc066a22044200370200200041f0066a220242eafdbbb690ac81edca00370300200020033602e006200041f8066a22072004360200200141286a101722032002290300107a200328020c200341106a28020047044010000b02402003280200220820032802042206100a2205450440410021020c010b410021022001410036022020014200370318200141186a200510582008200620012802182204200128021c220920046b100b417f4704402001200441016a20092004417f736a106b200710a201200521020b2004450d002001200436021c0b200328020c22040440200320043602100b20024504402007200041e0066a103a0b4100210420004188076a418002108501210920004188096a220242d0b4afbcbf988ce0b77f37030020004190096a4180021085012107200141286a101722032002290300107a200328020c200341106a28020047044010000b02402003280200220820032802042206100a2205450d002001410036022020014200370318200141186a200510582008200620012802182202200128021c220620026b100b417f4704402001200241016a20062002417f736a106b200710a501200521040b2002450d002001200236021c0b200328020c22020440200320023602100b200445044020072009418002103c1a0b41002102200041b00b6a4100360200200041ac0b6a200041a80b6a2204360200200041a00b6a220542f4ffce959b97c9c1d500370300200041980b6a4100360200200041940b6a200041900b6a2207360200200020073602900b20042004360200200141286a101722032005290300107a200328020c200341106a28020047044010000b02402003280200220620032802042209100a2208450d002001410036022020014200370318200141186a200810582006200920012802182205200128021c220620056b100b417f4704402001200541016a20062005417f736a106b200410a701200821020b2005450d002001200536021c0b200328020c22050440200320053602100b200245044020042007103e0b200042003700b80b41002104200041c80b6a4100360000200041c00b6a4200370000200041d80b6a22054200370000200041d00b6a220242affad78bbfdecaa6f300370300200041e00b6a4200370000200041e80b6a4100360000200141286a101722032002290300107a200328020c200341106a28020047044010000b02402003280200220820032802042206100a2207450d002001410036022020014200370318200141186a200710582008200620012802182202200128021c220920026b100b417f4704402001200241016a20092002417f736a106b200510ab01200721040b2002450d002001200236021c0b200328020c22020440200320023602100b20044504402005200041b80b6a2203290300370300200541106a200341106a280200360200200541086a200341086a2903003703000b200141406b240020000b973102087f027e230041c0086b22052400200541c0066a10172201200041d00b6a22022903001079101520012002290300107a200041d80b6a2102200128020c200141106a28020047044010000b2001280204210720012802002106200541c0046a10172104200210ac012108200420054180026a10b201220310b3012004200820032802046a20032802006b1015200541a0026a200241106a280000220836020020054198026a200241086a290000220937030020052002290000220a37039002200541b0026a2009370300200541b8026a2008360200200541086a2009370300200541106a20083602002005200a3703a8022005200a370300200541d0026a2008360200200541c8026a20093703002005200a3703c00202402004200541c0026a4114105d220228020c200241106a280200460440200241046a2104200228020021080c010b200241046a2104100020022802002108200228020c2002280210460d0010000b2006200720082004280200100c200328020022040440200320043602040b200228020c22030440200220033602100b200128020c22020440200120023602100b200541c0066a10172202200041a00b6a22012903001079101520022001290300107a200041a80b6a2104200228020c200241106a28020047044010000b2002280204210820022802002107200541c0046a10172101200410a90121062001200541c0026a10b201220310b3012001200620032802046a20032802006b10152001200410aa010240200128020c200141106a280200460440200141046a2104200128020021060c010b200141046a2104100020012802002106200128020c2001280210460d0010000b2007200820062004280200100c200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200041a80b6a10a801200041900b6a10a801200541a8026a1017220120004188096a22022903001079101520012002290300107a20004190096a2104200128020c200141106a28020047044010000b200128020421082001280200210720054190026a10172102200410a6012106200220054180026a10b201220310b3012002200620032802046a20032802006b101520052004418002103c220541c0026a2005418002103c1a200541c0046a200541c0026a418002103c1a200541c0066a200541c0046a418002103c1a02402002200541c0066a418002105d220228020c200241106a280200460440200241046a2104200228020021060c010b200241046a2104100020022802002106200228020c2002280210460d0010000b2007200820062004280200100c200328020022040440200320043602040b200228020c22030440200220033602100b200128020c22020440200120023602100b200541c0066a10172202200041f0066a22012903001079101520022001290300107a200041f8066a2104200228020c200241106a28020047044010000b2002280204210820022802002107200541c0046a10172101200410a30121062001200541c0026a10b201220310b3012001200620032802046a20032802006b10152001200410a4010240200128020c200141106a280200460440200141046a2104200128020021060c010b200141046a2104100020012802002106200128020c2001280210460d0010000b2007200820062004280200100c200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a10172202200041c8066a22012903001079101520022001290300107a200041d0066a2104200228020c200241106a28020047044010000b2002280204210820022802002107200541c0046a10172101200410a00121062001200541c0026a10b201220310b3012001200620032802046a20032802006b10152001200410a1010240200128020c200141106a280200460440200141046a2104200128020021060c010b200141046a2104100020012802002106200128020c2001280210460d0010000b2007200820062004280200100c200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a10172202200041b8056a22012903001079101520022001290300107a200041c0056a2104200228020c200241106a28020047044010000b2002280204210820022802002107200541c0046a101721012004109c0121062001200541c0026a10b201220310b3012001200620032802046a20032802006b101520012004109d010240200128020c200141106a280200460440200141046a2104200128020021060c010b200141046a2104100020012802002106200128020c2001280210460d0010000b2007200820062004280200100c200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a10172202200041a8046a22012903001079101520022001290300107a200041b0046a2104200228020c200241106a28020047044010000b2002280204210820022802002107200541c0046a1017210120002802b004200041b4046a28020010990121062001200541c0026a10b201220310b3012001200620032802046a20032802006b10152001200410160240200128020c200141106a280200460440200141046a2104200128020021060c010b200141046a2104100020012802002106200128020c2001280210460d0010000b2007200820062004280200100c200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200041b0046a28020022010440200041b4046a20013602000b200028029804220104402000419c046a20013602000b200541c0066a1017220220004180046a22012903001079101520022001290300107a20004188046a2104200228020c200241106a28020047044010000b2002280204210820022802002107200541c0046a10172101200410960121062001200541c0026a10b201220310b3012001200620032802046a20032802006b1015200120041097010240200128020c200141106a280200460440200141046a2104200128020021060c010b200141046a2104100020012802002106200128020c2001280210460d0010000b2007200820062004280200100c200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a10172202200041d8036a22012903001079101520022001290300107a200041e0036a2104200228020c200241106a28020047044010000b2002280204210820022802002107200541c0046a10172101200410930121062001200541c0026a10b201220310b3012001200620032802046a20032802006b1015200120041094010240200128020c200141106a280200460440200141046a2104200128020021060c010b200141046a2104100020012802002106200128020c2001280210460d0010000b2007200820062004280200100c200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200041e0036a28020022010440200041e4036a20013602000b20002802c80322010440200041cc036a20013602000b200541c0046a10172202200041b8036a22012903001079101520022001290300107a200228020c200241106a28020047044010000b2002280204210420022802002108200541c0026a10172101200541d8066a4100360200200541d0066a4200370300200541c8066a4200370300200542003703c006200541c0066a20002903c00310b40120052802c0062107200541c0066a410472101b2001200541c0066a10b201220310b3012001200720032802046a20032802006b1015200120002903c003107a0240200128020c200141106a280200460440200141046a2107200128020021060c010b200141046a2107100020012802002106200128020c2001280210460d0010000b2008200420062007280200100c200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0046a10172202200041a0036a22012903001079101520022001290300107a200228020c200241106a28020047044010000b2002280204210420022802002108200541c0026a10172101200541d8066a4100360200200541d0066a4200370300200541c8066a4200370300200542003703c006200541c0066a20002802a803101f20052802c0062107200541c0066a410472101b2001200541c0066a10b201220310b3012001200720032802046a20032802006b1015200120002802a80310200240200128020c200141106a280200460440200141046a2107200128020021060c010b200141046a2107100020012802002106200128020c2001280210460d0010000b2008200420062007280200100c200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a1017220220004188036a22012903001079101520022001290300107a200228020c200241106a28020047044010000b2002280204210420022802002108200541c0046a1017210120002903900310900121072001200541c0026a10b201220310b3012001200720032802046a20032802006b101520012000290390031091010240200128020c200141106a280200460440200141046a2107200128020021060c010b200141046a2107100020012802002106200128020c2001280210460d0010000b2008200420062007280200100c200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a10172202200041f0026a22012903001079101520022001290300107a200228020c200241106a28020047044010000b2002280204210420022802002108200541c0046a1017210120002802f802108e0121072001200541c0026a10b201220310b3012001200720032802046a20032802006b1015200120002802f802108c010240200128020c200141106a280200460440200141046a2107200128020021060c010b200141046a2107100020012802002106200128020c2001280210460d0010000b2008200420062007280200100c200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a10172202200041d8026a22012903001079101520022001290300107a200228020c200241106a28020047044010000b2002280204210420022802002108200541c0046a1017210120002f01e002108b0121072001200541c0026a10b201220310b3012001200720032802046a20032802006b1015200120002e01e002108c010240200128020c200141106a280200460440200141046a2107200128020021060c010b200141046a2107100020012802002106200128020c2001280210460d0010000b2008200420062007280200100c200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200041c0026a200041c8026a10b501200541c0066a1017220220004188026a22012903001079101520022001290300107a20004190026a2104200228020c200241106a28020047044010000b2002280204210820022802002107200541c0046a10172101200410880121062001200541c0026a10b201220310b3012001200620032802046a20032802006b1015200120041089010240200128020c200141106a280200460440200141046a2104200128020021060c010b200141046a2104100020012802002106200128020c2001280210460d0010000b2007200820062004280200100c200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a10172202200041c8016a22012903001079101520022001290300107a200041d0016a2104200228020c200241106a28020047044010000b2002280204210820022802002107200541c0046a10172101200410830121062001200541c0026a10b201220310b3012001200620032802046a20032802006b1015200120041084010240200128020c200141106a280200460440200141046a2104200128020021060c010b200141046a2104100020012802002106200128020c2001280210460d0010000b2007200820062004280200100c200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200041a8016a200041b0016a10b501200541c0066a1017220220004190016a22012903001079101520022001290300107a200228020c200241106a28020047044010000b2002280204210420022802002108200541c0046a1017210120002d009801107421072001200541c0026a10b201220310b3012001200720032802046a20032802006b1015200120002d00980110200240200128020c200141106a280200460440200141046a2107200128020021060c010b200141046a2107100020012802002106200128020c2001280210460d0010000b2008200420062007280200100c200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a10172201200041f0006a22022903001079101520012002290300107a200041f8006a2104200128020c200141106a28020047044010000b2001280204210820012802002107200541c0046a101721022004107d21062002200541c0026a10b201220310b3012002200620032802046a20032802006b101502402002200520041018101d220228020c200241106a280200460440200241046a2104200228020021060c010b200241046a2104100020022802002106200228020c2002280210460d0010000b2007200820062004280200100c200328020022040440200320043602040b200228020c22030440200220033602100b200128020c22020440200120023602100b200541c0066a10172202200041d0006a22012903001079101520022001290300107a200228020c200241106a28020047044010000b2002280204210420022802002108200541c0046a101721012000290358107921072001200541c0026a10b201220310b3012001200720032802046a20032802006b101520012000290358107a0240200128020c200141106a280200460440200141046a2107200128020021060c010b200141046a2107100020012802002106200128020c2001280210460d0010000b2008200420062007280200100c200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a10172202200041386a22012903001079101520022001290300107a200228020c200241106a28020047044010000b2002280204210420022802002108200541c0046a101721012000280240107821072001200541c0026a10b201220310b3012001200720032802046a20032802006b10152001200028024010200240200128020c200141106a280200460440200141046a2107200128020021060c010b200141046a2107100020012802002106200128020c2001280210460d0010000b2008200420062007280200100c200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a10172202200041206a22012903001079101520022001290300107a200228020c200241106a28020047044010000b2002280204210420022802002108200541c0046a1017210120002f0128107621072001200541c0026a10b201220310b3012001200720032802046a20032802006b1015200120002f012810200240200128020c200141106a280200460440200141046a2107200128020021060c010b200141046a2107100020012802002106200128020c2001280210460d0010000b2008200420062007280200100c200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a1017220220002903081079101520022000290308107a200228020c200241106a28020047044010000b2002280204210420022802002108200541c0046a1017210120002d0010107421072001200541c0026a10b201220310b3012001200720032802046a20032802006b1015200120002d001010200240200128020c200141106a280200460440200141046a2107200128020021060c010b200141046a2107100020012802002106200128020c2001280210460d0010000b2008200420062007280200100c200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0086a24000b2601017f02402000280204450d0020002802002d000041c001490d00200010b60121010b20010b800101037f230041106b22012400200010ae0102400240200010af01450d002000280204450d0020002802002d000041c001490d010b10000b200141086a200010b001200128020c220041024f044010000b200128020821020340200004402000417f6a210020022d00002103200241016a21020c010b0b200141106a240020030b5801027f230041206b22012400200141186a4100360200200141106a4200370300200141086a42003703002001420037030020012000ad42ff01834200105b210020012802002102200041046a101b200141206a240020020b8b0101037f230041106b22012400200010ae0102400240200010af01450d002000280204450d0020002802002d000041c001490d010b10000b200141086a200010b001200128020c220041034f044010000b200128020821030340200004402000417f6a210020032d00002002410874722102200341016a21030c010b0b200141106a2400200241ffff03710b5401017f230041206b22012400200141186a4100360200200141106a4200370300200141086a4200370300200142003703002001200041ffff0371101f200128020021002001410472101b200141206a240020000b860101037f230041106b22012400200010ae0102400240200010af01450d002000280204450d0020002802002d000041c001490d010b10000b200141086a200010b001200128020c220041054f044010000b200128020821030340200004402000417f6a210020032d00002002410874722102200341016a21030c010b0b200141106a240020020b4f01017f230041206b22012400200141186a4100360200200141106a4200370300200141086a42003703002001420037030020012000101f200128020021002001410472101b200141206a240020000b5001027f230041206b22012400200141186a4100360200200141106a4200370300200141086a4200370300200142003703002001200010b401200128020021022001410472101b200141206a240020020b0a00200020014200105e0b1a0020004200370200200041086a4100360200200010b70120000ba40201057f230041206b22022400024002402000280204044020002802002d000041c001490d010b200241086a107b1a0c010b200241186a200010b001200010b80121030240024002400240200228021822000440200228021c220520034f0d010b41002100200241106a410036020020024200370308410021050c010b200241106a4100360200200242003703082000200520032003417f461b22046a21052004410a4b0d010b200220044101743a0008200241086a41017221030c010b200441106a4170712206104021032002200436020c20022006410172360208200220033602100b03402000200546450440200320002d00003a0000200341016a2103200041016a21000c010b0b200341003a00000b2001200241086a10b901200241206a24000b5801027f230041306b22012400200141286a4100360200200141206a4200370300200141186a420037030020014200370310200141106a200120001018101a210020012802102102200041046a101b200141306a240020020b0e002001200010734100473a00000b4401027f230041f00b6b2202240020001072410247044010000b200220004101106c200210ba01210020021070210320022000200111000020031071200241f00b6a24000b7b01027f230041900c6b220224002000106f200241086a10702103200241086a20011101002100200241f80b6a10172201200010bb01101520012000108c01200128020c200141106a28020047044010000b20012802002001280204100e200128020c22000440200120003602100b20031071200241900c6a24000b180020004200370200200041086a41003602002000107b1a0b2801017f230041206b22022400200241086a20004100106c200241086a2001107c200241206a24000b5001017f230041206b22012400200141186a4100360200200141106a4200370300200141086a4200370300200142003703002001200010bc01200128020021002001410472101b200141206a240020000b6e01027f230041406a2202240020004101101c2100200241386a4100360200200241306a4200370300200241286a420037030020024200370320200241206a200241106a20011018101a21032000200228022010152000200220011018101d1a200341046a101b200241406b24000be10201027f02402001450d00200041003a0000200020016a2203417f6a41003a000020014103490d00200041003a0002200041003a00012003417d6a41003a00002003417e6a41003a000020014107490d00200041003a00032003417c6a41003a000020014109490d002000410020006b41037122026a220341003602002003200120026b417c7122026a2201417c6a410036020020024109490d002003410036020820034100360204200141786a4100360200200141746a410036020020024119490d002003410036021820034100360214200341003602102003410036020c200141706a41003602002001416c6a4100360200200141686a4100360200200141646a41003602002002200341047141187222026b2101200220036a2102034020014120490d0120024200370300200241186a4200370300200241106a4200370300200241086a4200370300200241206a2102200141606a21010c000b000b20000b19002000107b1a2000410c6a107b1a200041186a107b1a20000b5701017f230041206b22022400200241086a20004100106c200241086a2001108201200241086a20004101106c200241086a2001410c6a107c200241086a20004102106c200241086a200141186a107c200241206a24000b7a01027f230041406a22012400200141186a4100360200200141106a4200370300200141086a4200370300200142003703002001410010192202200010bc012002200141306a2000410c6a1018101a200141206a200041186a1018101a41011019210020012802002102200041046a101b200141406b240020020ba40101047f230041e0006b2202240020004103101c2100200241d8006a4100360200200241d0006a4200370300200241c8006a420037030020024200370340200241406b200110bc01200241406b200241306a2001410c6a22031018101a200241206a200141186a22041018101a2105200020022802401015200020011084012000200241106a20031018101d200220041018101d1a200541046a101b200241e0006a24000b3902017f017e230041106b220124002001200010bd0120012903002102200141106a2400420020024201837d200242018885a74110744110750b6202027f017e230041206b22012400200141186a4100360200200141106a4200370300200141086a42003703002001420037030020012000ad42308622034230872003423f8710be01210020012802002102200041046a101b200141206a240020020b1301017e20002001ac22022002423f8710bf010b3302017f017e230041106b220124002001200010bd0120012903002102200141106a2400420020024201837d200242018885a70b5201027f230041206b22012400200141186a4100360200200141106a4200370300200141086a4200370300200142003703002001200010c001210020012802002102200041046a101b200141206a240020020b4202017f027e230041106b220124002001200010bd01200141086a290300210320012903002102200141106a2400420020024201837d2003423f86200242018884850b5701037f230041206b22012400200141186a4100360200200141106a4200370300200141086a420037030020014200370300200120002000423f8710be01210220012802002103200241046a101b200141206a240020030b0e00200020012001423f8710bf010bb10201047f230041d0006b22022400024002402000280204450d0020002802002d000041c001490d002000107221032001280208200128020022046b4101752003490440200120022003200128020420046b410175200141086a10c101220310c201200310c3010b200241286a200010c401200241186a200010c501200141086a21050340200228022c200228021c46044020022802302002280220460d030b2002200241286a10c6012002107521030240200128020422002001280208490440200020033b01002001200041026a3602040c010b200241386a2001200020012802006b410175220041016a10552000200510c10121002002280240220420033b01002002200441026a3602402001200010c201200010c3010b200241286a10c7010c000b000b10000b200241d0006a24000b9c0101037f230041206b22012400200141186a4100360200200141106a4200370300200141086a420037030020014200370300024020002802002000280204460440200110c8010c010b200141001019210220002802042103200028020021000340200020034604402002410110191a05200220002f0100101f200041026a21000c010b0b0b200128020021002001410472101b200141206a240020000b4301017f2000200128020420012802006b410175101c21022001280204210020012802002101034020002001470440200220012f01001020200141026a21010c010b0b0be20201057f23004190016b22022400024002402000280204450d0020002802002d000041c001490d00200241c8006a200010c401200241386a200010c501200241146a21040340200228024c200228023c46044020022802502002280240460d030b200241206a200241c8006a10c601200241086a107b21002004107b2105200241206a10c901410247044010000b20024180016a107b2103200241e8006a200241206a4100106c200241e8006a2003107c2000200310b901200241d8006a107b2103200241e8006a200241206a4101106c200241e8006a2003107c2005200310b9012001200241e8006a2000104322062802004504404128104022032002290308370210200341186a200241106a280200360200200010b701200341246a200441086a2802003602002003411c6a2004290200370200200510b701200120022802682006200310450b200241c8006a10c7010c000b000b10000b20024190016a24000bd00101047f230041e0006b22012400200141206a4100360200200141186a4200370300200141106a42003703002001420037030802402000280208450440200141086a10c8010c010b200041046a2103200141086a410010192102200141346a2104200028020021000340200020034604402002410110191a05200141286a200041106a1051200241001019200141d0006a200141286a1018101a200141406b20041018101a410110191a2000103021000c010b0b0b20012802082100200141086a410472101b200141e0006a240020000b6101027f230041206b2202240020002001280208101c2103200141046a210020012802002101034020002001460440200241206a24000520034102101c200241106a200141106a1018101d20022001411c6a1018101d1a2001103021010c010b0b0bce0101037f230041206b22022400024002402000280204044020002802002d000041c001490d010b20024100360208200242003703000c010b200241186a200010b00120022802182103200241106a200010b00120022802102104200010b80121002002410036020820024200370300200020046a20036b2200450d0020022000104b20004101480d002002200228020420032000103c20006a3602040b2001280200044020014100360208200142003702000b2001200228020036020020012002290204370204200241206a24000b5301017f230041206b22022400200241186a4100360200200241106a4200370300200241086a4200370300200242003703002002200020011014210020022802002101200041046a101b200241206a240020010b2c01037f200041f8006a21022000210103402001107b21032001410c6a21012003410c6a2002470d000b20000b6101037f230041306b22022400200010c901410a47044010000b03402003410a460440200241306a240005200241206a107b2104200241086a20002003106c200241086a2004107c2001200410b9012001410c6a2101200341016a21030c010b0b0b800101037f230041306b22012400200141186a4100360200200141106a4200370300200141086a42003703002001420037030020014100101921030340200241f800464504402003200141206a200020026a1018101a1a2002410c6a21020c010b0b200341011019210220012802002103200241046a101b200141306a240020030b4401027f230041106b220224002000410a101c2103410021000340200041f800460440200241106a24000520032002200020016a1018101d1a2000410c6a21000c010b0b0b10002000107b1a2000410036020c20000b5d01027f230041306b22022400200010c901410247044010000b200241206a107b2103200241086a20004100106c200241086a2003107c2001200310b901200241086a20004101106c2001200241086a108d0136020c200241306a24000b7301027f230041406a22012400200141286a4100360200200141206a4200370300200141186a4200370300200142003703102001200010382100200141106a41001019200141306a20001018101a200028020c10c00141011019210020012802102102200041046a101b200141406b240020020b2a01017f230041106b2202240020004102101c200220011018101d200128020c108c01200241106a24000bd70101047f230041d0006b22022400024002402000280204450d0020002802002d000041c001490d00200241406b200010c401200241306a200010c501200241106a210403402002280244200228023446044020022802482002280238460d030b200241186a200241406b10c601200241186a200241086a107b2200107c2001200241cc006a200010432205280200450440411c104022032002290308370210200341186a2004280200360200200010b7012001200228024c2005200310450b200241406b10c7010c000b000b10000b200241d0006a24000b9e0101037f230041306b22012400200141186a4100360200200141106a4200370300200141086a42003703002001420037030002402000280208450440200110c8010c010b200041046a21032001410010192102200028020021000340200020034604402002410110191a052002200141206a200041106a1018101a1a2000103021000c010b0b0b200128020021002001410472101b200141306a240020000b4f01027f230041106b2202240020002001280208101c2103200141046a210020012802002101034020002001460440200241106a24000520032002200141106a1018101d1a2001103021010c010b0b0b9f0101027f23004190046b22022400200010ae0120024188046a200010b001200228028c042103024002402000280204450d0020034180024b0d0020002802002d000041c001490d010b10000b20024188026a4180021085011a200220034180022003418002491b22006b4188046a2002280288042000103c1a200241086a20024188026a418002103c1a2001200241086a418002103c1a20024190046a24000bc00101037f230041a0086b2201240020014198026a410036020020014190026a420037030020014188026a4200370300200142003703800220012000418002103c220041a0026a2000418002103c1a200041a0046a200041a0026a418002103c1a200041a0066a200041a0046a418002103c1a41012103024003402002418002460d01200041a0066a20026a2101200241016a210220012d0000450d000b41830221030b200020033602800220004180026a410472101b200041a0086a240020030bec0101037f230041d0006b22022400024002402000280204450d0020002802002d000041c001490d00200241406b200010c401200241306a200010c501200241106a210403402002280244200228023446044020022802482002280238460d030b200241186a200241406b10c601200241186a200241086a107b2203107c411410402200410036020020002002290308370208200041106a2004280200360200200310b70120002001360204200128020021032001200036020020002003360200200320003602042001200128020841016a360208200241406b10c7010c000b000b10000b200241d0006a24000b4d01037f02402000280208450d00200028020422012802002202200028020022032802043602042000410036020820032802042002360200034020002001460d01200128020421010c000b000b0b9d0101037f230041306b22012400200141186a4100360200200141106a4200370300200141086a42003703002001420037030002402000280208450440200110c8010c010b200041046a2102200141001019210303402002280200220220004604402003410110191a052003200141206a200241086a1018101a1a200241046a21020c010b0b0b200128020021022001410472101b200141306a240020020b4e01027f230041106b22032400200141046a210220002001280208101c21000340200228020022022001460440200341106a24000520002003200241086a1018101d1a200241046a21020c010b0b0bd10102037f027e230041406a22022400200010ae01200241386a200010b001200228023c2103024002402000280204450d00200341144b0d0020002802002d000041c001490d010b10000b200241306a22004100360200200241286a220442003703002002420037032020022003411420034114491b22036b41346a20022802382003103c1a200241186a20002802002200360200200241106a20042903002205370300200220022903202206370308200141106a2000360000200141086a200537000020012006370000200241406b24000b850202037f027e23004180016b22012400200141306a4100360200200141286a4200370300200141206a4200370300200141086a200041086a2900002204370300200141106a200041106a280000220236020020014200370318200120002900002205370300200141406b2004370300200141c8006a2002360200200141d8006a2004370300200141e0006a20023602002001200537033820012005370350200141f8006a2002360200200141f0006a200437030020012005370368410121020240034020034114460d01200141e8006a20036a2100200341016a210320002d0000450d000b411521020b20012002360218200141186a410472101b20014180016a240020020b750020004200370210200042ffffffff0f370208200020023602042000200136020002402003410871450d00200010cd0120024f0d002003410471044010000c010b200042003702000b02402003411071450d00200010cd0120024d0d0020034104710440100020000f0b200042003702000b20000b4101017f200028020445044010000b0240200028020022012d0000418101470d00200028020441014d047f100020002802000520010b2c00014100480d0010000b0b990101037f200028020445044041000f0b200010ae01200028020022022c0000220141004e044020014100470f0b027f4101200141807f460d001a200141ff0171220341b7014d0440200028020441014d047f100020002802000520020b2d00014100470f0b4100200341bf014b0d001a2000280204200141ff017141ca7e6a22014d047f100020002802000520020b20016a2d00004100470b0bd60101047f200110b8012204200128020422024b04401000200128020421020b200128020021052000027f02400240200204404100210120052c00002203417f4a0d01027f200341ff0171220141bf014d04404100200341ff017141b801490d011a200141c97e6a0c010b4100200341ff017141f801490d001a200141897e6a0b41016a21010c010b4101210120050d000c010b41002103200120046a20024b0d0020022001490d00410020022004490d011a200120056a2103200220016b20042004417f461b0c010b41000b360204200020033602000bc20101057f230041406a22022400200241286a101722032000290300107a200328020c200341106a28020047044010000b02402003280200220020032802042205100a22064504400c010b2002410036022020024200370318200241186a200610582000200520022802182200200228021c220520006b100b417f47044020012002200041016a20052000417f736a106b10ba013a0000200621040b2000450d002002200036021c0b200328020c22000440200320003602100b200241406b240020040b3000200041003602082000420037020020004101104b200028020441fe013a00002000200028020441016a36020420000b6101037f200028020c200041106a28020047044010000b200028020422022001280204200128020022036b22016a220420002802084b047f20002004105c20002802040520020b20002802006a20032001103c1a2000200028020420016a3602040b0b00200020014200105b1a0b8e0201067f230041406a22042400200441286a1017220220002903001079101520022000290300107a200228020c200241106a28020047044010000b2002280204210620022802002107200441106a1017210020012d000010bb0121052000200410b201220310b3012000200520032802046a20032802006b1015200020012c0000108c010240200028020c200041106a280200460440200041046a2101200028020021050c010b200041046a2101100020002802002105200028020c2000280210460d0010000b2007200620052001280200100c200328020022010440200320013602040b200028020c22030440200020033602100b200228020c22000440200220003602100b200441406b24000b820101047f230041106b2201240002402000280204450d0020002802002d000041c001490d00200141086a200010d101200128020c210003402000450d0120014100200128020822032003200010cf0122046a20034520002004497222031b3602084100200020046b20031b2100200241016a21020c000b000b200141106a240020020b2201017f03402001410c470440200020016a4100360200200141046a21010c010b0b0b800301037f200028020445044041000f0b200010ae0141012102024020002802002c00002201417f4a0d00200141ff0171220341b7014d0440200341807f6a0f0b02400240200141ff0171220141bf014d0440024020002802042201200341c97e6a22024d047f100020002802040520010b4102490d0020002802002d00010d0010000b200241054f044010000b20002802002d000145044010000b4100210241b7012101034020012003460440200241384f0d030c0405200028020020016a41ca7e6a2d00002002410874722102200141016a21010c010b000b000b200141f7014d0440200341c07e6a0f0b024020002802042201200341897e6a22024d047f100020002802040520010b4102490d0020002802002d00010d0010000b200241054f044010000b20002802002d000145044010000b4100210241f701210103402001200346044020024138490d0305200028020020016a418a7e6a2d00002002410874722102200141016a21010c010b0b0b200241ff7d490d010b10000b20020b5c00024020002d0000410171450440200041003b01000c010b200028020841003a00002000410036020420002d0000410171450d00200041003602000b20002001290200370200200041086a200141086a280200360200200110b7010b3902017f017e230041106b220124002001200010bd0120012903002102200141106a2400420020024201837d200242018885a74118744118750b6202027f017e230041206b22012400200141186a4100360200200141106a4200370300200141086a42003703002001420037030020012000ad42388622034238872003423f8710be01210020012802002102200041046a101b200141206a240020020b2701017f230041106b22022400200041001019200220011018101a410110191a200241106a24000ba10102027f027e230041106b22022400200110ae0102400240200110af01450d002001280204450d0020012802002d000041c001490d010b10000b200241086a200110b001200228020c220141114f044010000b20022802082103034020010440200542088620044238888421052001417f6a210120033100002004420886842104200341016a21030c010b0b2000200437030020002005370308200241106a24000b2301017e20002002423f87220320014201868520024201862001423f8884200385105b0b2301017e20002002423f87220320014201868520024201862001423f8884200385105e0b1301017e20002001ac22022002423f8710be010b4c01017f2000410036020c200041106a2003360200200104402001105321040b200020043602002000200420024101746a22023602082000200420014101746a36020c2000200236020420000b870101037f200120012802042000280204200028020022046b22036b2202360204200341004a0440200220042003103c1a200128020421020b200028020021032000200236020020012003360204200028020421022000200128020836020420012002360208200028020821022000200128020c3602082001200236020c200120012802043602000b2b01027f200028020821012000280204210203402001200247044020002001417e6a22013602080c010b0b0b0b0020002001410110ca010b0b0020002001410010ca010b170020002001280204200141086a280200411c10ad011a0bb70102057f017e230041106b22032400200041046a210102402000280200220204402001280200220504402005200041086a2802006a21040b20002004360204200041086a2002360200200341086a200141002004200210cf0110d00120002003290308220637020420004100200028020022012006422088a76b2202200220014b1b3602000c010b200020012802002201047f2001200041086a2802006a0541000b360204200041086a41003602000b200341106a24000b3901017f027f200041186a28020022010440200041086a280200200041146a2802002001105a0c010b20000b2201200128020041016a3602000b220002402000280204044020002802002d000041bf014b0d010b10000b200010b6010be70101037f230041106b2204240020004200370200200041086a410036020020012802042103024002402002450440200321020c010b410021022003450d002003210220012802002d000041c001490d00200441086a200110d10120004100200428020c220120042802082202200110cf0122032003417f461b20024520012003497222031b220536020820004100200220031b3602042000200120056b3602000c010b20012802002103200128020421012000410036020020004100200220016b20034520022001497222021b36020820004100200120036a20021b3602040b200441106a24000b3501017f230041106b220041908c0436020c41800c200028020c41076a417871220036020041840c200036020041880c3f003602000b100020020440200020012002103c1a0b0b3001017f200028020445044041000f0b4101210120002802002c0000417f4c047f200010ce01200010b8016a0520010b0b5b00027f027f41002000280204450d001a410020002802002c0000417f4a0d011a20002802002d0000220041bf014d04404100200041b801490d011a200041c97e6a0c010b4100200041f801490d001a200041897e6a0b41016a0b0b2901017f230041206b22022400200241086a20002001411410ad0110cd012100200241206a240020000b5b01027f2000027f0240200128020022054504400c010b200220036a200128020422014b0d0020012002490d00410020012003490d011a200220056a2104200120026b20032003417f461b0c010b41000b360204200020043602000b2401017f200110b801220220012802044b044010000b20002001200110ce01200210d0010b7b01037f0340024020002802102201200028020c460d00200141786a2802004504401000200028021021010b200141786a22022002280200417f6a220336020020030d002000200236021020002001417c6a2802002201200028020420016b220210026a10d301200120002802006a22012002200110030c010b0b0b3601017f200028020820014904402001106720002802002000280204103c210220002001360208200020023602000b200020013602040b0bfa0301004180080bf203746f70696331006461746131006a735f636f6e7472616374006576656e740073657455696e7433324576740073657455696e743136457674007472616e7366657200696e69740073657455696e74380067657455696e74380073657455696e7431360067657455696e7431360073657455696e7433320067657455696e7433320073657455696e7436340067657455696e74363400736574537472696e6700676574537472696e6700736574426f6f6c00676574426f6f6c00736574436861720067657443686172007365744d657373616765006765744d657373616765007365744d794d657373616765006765744d794d65737361676500736574496e743800676574496e743800736574496e74313600676574496e74313600736574496e74333200676574496e74333200736574496e74363400676574496e74363400736574566563746f7200676574566563746f72007365744d6170006765744d617000746573744d756c7469506172616d730073657442797465730067657442797465730073657441727261790067657441727261790073657450616972006765745061697200736574536574006765745365740073657446697865644861736800676574466978656448617368007365744c697374006765744c69737400736574416464726573730067657441646472657373' +abi = [{"constant":false,"input":[{"name":"input","type":"string[10]"}],"name":"setArray","output":"void","type":"Action"},{"constant":false,"input":[{"name":"input","type":"FixedHash<256>"}],"name":"setFixedHash","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getFixedHash","output":"FixedHash<256>","type":"Action"},{"constant":true,"input":[],"name":"getChar","output":"int8","type":"Action"},{"baseclass":[],"fields":[{"name":"head","type":"string"}],"name":"message","type":"struct"},{"constant":false,"input":[{"name":"msg","type":"message"}],"name":"setMessage","output":"void","type":"Action"},{"constant":false,"input":[{"name":"input","type":"int32"}],"name":"setInt32","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getPair","output":"pair","type":"Action"},{"anonymous":false,"input":[{"name":"topic","type":"string"},{"name":"arg1","type":"string"}],"name":"transfer","topic":1,"type":"Event"},{"anonymous":false,"input":[{"name":"topic","type":"string"},{"name":"arg1","type":"string"},{"name":"arg2","type":"uint16"}],"name":"setUint16Evt","topic":1,"type":"Event"},{"constant":false,"input":[{"name":"addr","type":"FixedHash<20>"}],"name":"setAddress","output":"void","type":"Action"},{"anonymous":false,"input":[{"name":"topic1","type":"string"},{"name":"topic2","type":"uint32"},{"name":"arg1","type":"string"},{"name":"arg2","type":"uint32"},{"name":"arg3","type":"uint32"}],"name":"setUint32Evt","topic":2,"type":"Event"},{"constant":false,"input":[],"name":"init","output":"void","type":"Action"},{"constant":false,"input":[{"name":"input","type":"uint8"}],"name":"setUint8","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getUint8","output":"uint8","type":"Action"},{"constant":false,"input":[{"name":"input","type":"uint16"}],"name":"setUint16","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getUint16","output":"uint16","type":"Action"},{"constant":false,"input":[{"name":"input","type":"uint32"}],"name":"setUint32","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getUint32","output":"uint32","type":"Action"},{"constant":false,"input":[{"name":"input","type":"uint64"}],"name":"setUint64","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getUint64","output":"uint64","type":"Action"},{"constant":false,"input":[{"name":"input","type":"string"}],"name":"setString","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getString","output":"string","type":"Action"},{"constant":false,"input":[{"name":"input","type":"bool"}],"name":"setBool","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getBool","output":"bool","type":"Action"},{"constant":false,"input":[{"name":"input","type":"int8"}],"name":"setChar","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getMessage","output":"message","type":"Action"},{"baseclass":["message"],"fields":[{"name":"body","type":"string"},{"name":"end","type":"string"}],"name":"my_message","type":"struct"},{"constant":false,"input":[{"name":"msg","type":"my_message"}],"name":"setMyMessage","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getMyMessage","output":"my_message","type":"Action"},{"constant":false,"input":[{"name":"input","type":"int8"}],"name":"setInt8","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getInt8","output":"int8","type":"Action"},{"constant":false,"input":[{"name":"input","type":"int16"}],"name":"setInt16","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getInt16","output":"int16","type":"Action"},{"constant":true,"input":[],"name":"getInt32","output":"int32","type":"Action"},{"constant":false,"input":[{"name":"input","type":"int64"}],"name":"setInt64","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getInt64","output":"int64","type":"Action"},{"constant":false,"input":[{"name":"vec","type":"uint16[]"}],"name":"setVector","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getVector","output":"uint16[]","type":"Action"},{"constant":false,"input":[{"name":"input","type":"map"}],"name":"setMap","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getMap","output":"map","type":"Action"},{"constant":false,"input":[{"name":"msg","type":"message"},{"name":"input1","type":"int32"},{"name":"input2","type":"bool"}],"name":"testMultiParams","output":"void","type":"Action"},{"constant":false,"input":[{"name":"input","type":"uint8[]"}],"name":"setBytes","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getBytes","output":"uint8[]","type":"Action"},{"constant":true,"input":[],"name":"getArray","output":"string[10]","type":"Action"},{"constant":false,"input":[{"name":"input","type":"pair"}],"name":"setPair","output":"void","type":"Action"},{"constant":false,"input":[{"name":"input","type":"set"}],"name":"setSet","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getSet","output":"set","type":"Action"},{"constant":false,"input":[{"name":"input","type":"list"}],"name":"setList","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getList","output":"list","type":"Action"},{"constant":true,"input":[],"name":"getAddress","output":"FixedHash<20>","type":"Action"}] + +# Instantiate and deploy contract +Payable = platon.wasmcontract(abi=abi, bytecode=bytecode,vmtype=1) + +tx_hash = Payable.constructor().transact( + { + 'from':from_address, + 'gas':1500000, + } +) +# Wait for the transaction to be mined, and get the transaction receipt +tx_receipt = platon.waitForTransactionReceipt(tx_hash) + +# Create the contract instance with the newly-deployed address +greeter = platon.wasmcontract(address=tx_receipt.contractAddress, abi=abi,vmtype=1) + +# tx_hash = greeter.functions.setUint8(100).transact( +# { +# 'from': from_address, +# 'gas': 1500000, +# } +# ) +# +# tx_receipt = platon.waitForTransactionReceipt(tx_hash) +# print(tx_receipt) +# +# topic_param = greeter.events.transfer().processReceipt(tx_receipt) +# print(topic_param) +# (AttributeDict({'args': AttributeDict({'topic': 'js_contract', 'arg1': 'event'}), 'event': 'transfer', 'logIndex': 0, 'transactionIndex': 0, 'transactionHash': HexBytes('0x5c6cb9d5146ec2eb9efc71c12cfda9c52d86a4b314fb1180f8ae60f70a4ff698'), 'address': 'lax15cwddzr4rp0u2rugpuap8huzhs5h00p9349xac', 'blockHash': HexBytes('0x26204750c4f4d6cc9a4bbce7f3094be6fc3644daa1664d1c0a3b22f11183f756'), 'blockNumber': 1477530}),) + +# tx_hash = greeter.functions.setUint16(100).transact( +# { +# 'from': from_address, +# 'gas': 1500000, +# } +# ) +# +# tx_receipt = platon.waitForTransactionReceipt(tx_hash) +# print(tx_receipt) +# +# topic_param = greeter.events.setUint16Evt().processReceipt(tx_receipt) +# print(topic_param) +# (AttributeDict({'args': AttributeDict({'topic': 'topic1', 'arg1': 'data1', 'arg2': 100}), 'event': 'setUint16Evt', 'logIndex': 0, 'transactionIndex': 0, 'transactionHash': HexBytes('0xe1461e9b1dd08ea3f9e99dd5b9cf671dd954fa90bde8dc41f3f30b3cf38fd552'), 'address': 'lax1pxanl0ghv96dqt95maqqc4m55s325s73dkcu2x', 'blockHash': HexBytes('0xb7f75236055d440671021c03dc5149864c62df77b0c9b987b404721eed552220'), 'blockNumber': 1477654}),) +tx_hash = greeter.functions.setUint32(1000).transact( + { + 'from': from_address, + 'gas': 1500000, + } +) + +tx_receipt = platon.waitForTransactionReceipt(tx_hash) +print(tx_receipt) + +topic_param = greeter.events.setUint32Evt().processReceipt(tx_receipt) +print(topic_param) +# (AttributeDict({'args': AttributeDict({'topic1': 'topic1', 'arg1': 'data1', 'arg2': 1000, 'arg3': 1000}), 'event': 'setUint32Evt', 'logIndex': 0, 'transactionIndex': 0, 'transactionHash': HexBytes('0xabac50c6a9d443d9f89065775f0f3d56ddeabd2f2a5e0e1f36d00db703b14d8b'), 'address': 'lax1sgsp74pce2vkgwqjd3rzmt55p70psmq7qvnqwn', 'blockHash': HexBytes('0x78f15fbacbc745dfd5b35b596d28b61ae2987b6ff9050dc39c716f383e505899'), 'blockNumber': 1477774}),) \ No newline at end of file diff --git a/tests/newwasm_test1.py b/tests/newwasm_test1.py new file mode 100644 index 0000000..e9a5aee --- /dev/null +++ b/tests/newwasm_test1.py @@ -0,0 +1,294 @@ +from client_sdk_python import Web3, HTTPProvider +from client_sdk_python.eth import PlatON +# import binascii +# f = open('D:/juzhen/JS_wasmtest1.wasm','rb') +# contents=f.read() +# bytecode=binascii.b2a_hex(contents) + +true = True +false = False + +# w3 = Web3(HTTPProvider("http://10.1.1.2:6789")) +# platon = PlatON(w3) +# print(w3.isConnected()) +# +# from_address = "lax1uqug0zq7rcxddndleq4ux2ft3tv6dqljphydrl" +# print(from_address) + +# send_privatekey = "983759fe9aac227c535b21d78792d79c2f399b1d43db46ae6d50a33875301557" + +w3 = Web3(HTTPProvider("http://10.1.1.51:6789")) +platon = PlatON(w3) +print(w3.isConnected()) + +from_address = "atx1c85wwztzpjefcvaev6wxpsrqp2gpfjyp6lmfqd" +print(from_address) + +send_privatekey = "a98e6baea6233965a0740e20e626c5500ecf16121547e8255ee5a28a4f08fc57" + +bytecode='0061736d0100000001681260027f7f0060017f017f60027f7f017f60017f0060037f7f7f0060037f7f7f017f60000060047f7f7f7f0060047f7f7f7f017f60027f7e0060017f017e60037f7e7e0060037f7e7e017f60017e017f60057f7f7f7f7f0060037e7e7f006000017f60027e7e017f02ce020f03656e760c706c61746f6e5f70616e6963000603656e760b706c61746f6e5f73686133000703656e760d726c705f6c6973745f73697a65000103656e760f706c61746f6e5f726c705f6c697374000403656e760e726c705f62797465735f73697a65000203656e7610706c61746f6e5f726c705f6279746573000403656e760d726c705f753132385f73697a65001103656e760f706c61746f6e5f726c705f75313238000f03656e7617706c61746f6e5f6765745f696e7075745f6c656e677468001003656e7610706c61746f6e5f6765745f696e707574000303656e7617706c61746f6e5f6765745f73746174655f6c656e677468000203656e7610706c61746f6e5f6765745f7374617465000803656e7610706c61746f6e5f7365745f7374617465000703656e760c706c61746f6e5f6576656e74000703656e760d706c61746f6e5f72657475726e000003c701c5010600020200050000010202020302020400000e0000000200010002000100020000010207000200020002000002050000020101020504070003030105000405020404000001050204030001050c00050b01000005080305000106060605040a0a030103010101010101010d0901000100000003000100020100010001010001010a0d0900010000010000020100010001000100000100000100030100000108030100020100090001030100010100000c0b02080003000000030301040604010102070003000405017001050505030100020608017f0141908c040b073904066d656d6f72790200115f5f7761736d5f63616c6c5f63746f7273000f0f5f5f66756e63735f6f6e5f65786974006a06696e766f6b650068090a010041010b0426272a2b0a97b602c501050010cb010baa0301097f230041c0016b22022400200241b90810112104200241e8006a410210122103200241d8006a20041013200241c8006a20001013200241406b4100360200200241386a4200370300200241306a420037030020024200370328200241286a20022802582204200228025c101420022802482205200228024c101421062003200228022810152003200241d8006a10162003200241c8006a1016200328020c200341106a28020047044010000b2003280204210720032802002108200241106a1017210020024180016a200110182101200241a8016a4100360200200241a0016a420037030020024198016a4200370300200242003703900120024190016a41001019200241b0016a20011018101a410110192109200228029001210a200941046a101b2000200a101520004101101c20024190016a20011018101d220028020c200041106a28020047044010000b2008200720002802002000280204100d200028020c22010440200020013602100b200641046a101b200504402002200536024c0b200404402002200436025c0b200328020c22000440200320003602100b200241c0016a24000b910101027f20004200370200200041086a410036020020012102024003402002410371044020022d0000450d02200241016a21020c010b0b2002417c6a21020340200241046a22022802002203417f73200341fffdfb776a7141808182847871450d000b0340200341ff0171450d01200241016a2d00002103200241016a21020c000b000b20002001200220016b105620000b1d0020001057200041146a41003602002000420037020c20002001101c0ba40201047f230041206b2202240020024100360218200242003703100240027f4100200128020420012d00002204410176200441017122051b2204450d001a2001280208200141016a20051b2103200241106a2004104b0340200404402002280214220120032d00003a00002002200141016a3602142004417f6a2104200341016a21030c010b0b2002280210210320022802140b220420036b41204d044020002004360204200020033602002000200228021836020820024100360218200242003703100c010b20024100360208200242003703002002412010582003200228021420036b200228020022042002280204220120046b10012000200136020420002004360200200020022802083602082003450d00200220033602140b200241206a24000b8b0101017f024020012002460440410121030c010b4101210302400240200220016b2202410146044020012c0000417f4c0d010c030b200241374b0d010b200241016a21030c010b2002105920026a41016a21030b027f200041186a28020022010440200041086a280200200041146a2802002001105a0c010b20000b2201200128020020036a36020020000b13002000280208200149044020002001105c0b0b1600200020012802002200200128020420006b105d1a0b190020001057200041146a41003602002000420037020c20000b4d01017f20004200370200200041086a2202410036020020012d0000410171450440200020012902003702002002200141086a28020036020020000f0b200020012802082001280204105620000bc30c02077f027e230041306b22042400200041046a2107027f20014101460440200041086a280200200041146a280200200041186a22022802002203105a280200210120022003417f6a3602002007105f4180104f044020072000410c6a280200417c6a10600b200141384f047f2001105920016a0520010b41016a2102200041186a28020022010440200041086a280200200041146a2802002001105a0c020b20000c010b02402007105f0d00200041146a28020022014180084f0440200020014180786a360214200041086a2201280200220228020021032001200241046a360200200420033602182007200441186a10610c010b2000410c6a2802002202200041086a2802006b4102752203200041106a2205280200220620002802046b220141027549044041802010402105200220064704400240200028020c220120002802102202470d0020002802082203200028020422064b04402000200320012003200320066b41027541016a417e6d41027422026a1062220136020c2000200028020820026a3602080c010b200441186a200220066b2201410175410120011b22012001410276200041106a10632102200028020c210320002802082101034020012003470440200228020820012802003602002002200228020841046a360208200141046a21010c010b0b200029020421092000200229020037020420022009370200200029020c21092000200229020837020c2002200937020820021064200028020c21010b200120053602002000200028020c41046a36020c0c020b02402000280208220120002802042202470d00200028020c2203200028021022064904402000200120032003200620036b41027541016a41026d41027422026a106522013602082000200028020c20026a36020c0c010b200441186a200620026b2201410175410120011b2201200141036a410276200041106a10632102200028020c210320002802082101034020012003470440200228020820012802003602002002200228020841046a360208200141046a21010c010b0b200029020421092000200229020037020420022009370200200029020c21092000200229020837020c2002200937020820021064200028020821010b2001417c6a2005360200200020002802082201417c6a22023602082002280200210220002001360208200420023602182007200441186a10610c010b20042001410175410120011b200320051063210241802010402106024020022802082201200228020c2203470d0020022802042205200228020022084b04402002200520012005200520086b41027541016a417e6d41027422036a106222013602082002200228020420036a3602040c010b200441186a200320086b2201410175410120011b22012001410276200241106a280200106321032002280208210520022802042101034020012005470440200328020820012802003602002003200328020841046a360208200141046a21010c010b0b20022902002109200220032902003702002003200937020020022902082109200220032902083702082003200937020820031064200228020821010b200120063602002002200228020841046a360208200028020c2105034020002802082005460440200028020421012000200228020036020420022001360200200228020421012002200536020420002001360208200029020c21092000200229020837020c2002200937020820021064052005417c6a210502402002280204220120022802002203470d0020022802082206200228020c22084904402002200120062006200820066b41027541016a41026d41027422036a106522013602042002200228020820036a3602080c010b200441186a200820036b2201410175410120011b2201200141036a4102762002280210106321062002280208210320022802042101034020012003470440200428022020012802003602002004200428022041046a360220200141046a21010c010b0b20022902002109200220042903183702002002290208210a20022004290320370208200420093703182004200a37032020061064200228020421010b2001417c6a200528020036020020022002280204417c6a3602040c010b0b0b200441186a20071066200428021c410036020041012102200041186a0b2201200128020020026a360200200441306a240020000ba10101037f41012103024002400240200128020420012d00002202410176200241017122041b220241014d0440200241016b0d032001280208200141016a20041b2c0000417f4c0d010c030b200241374b0d010b200241016a21030c010b2002105920026a41016a21030b027f200041186a28020022010440200041086a280200200041146a2802002001105a0c010b20000b2201200128020020036a36020020000bea0101047f230041106b22042400200028020422012000280210220241087641fcffff07716a2103027f410020012000280208460d001a2003280200200241ff07714102746a0b2101200441086a20001066200428020c210203400240200120024604402000410036021420002802082103200028020421010340200320016b41027522024103490d022000200141046a22013602040c000b000b200141046a220120032802006b418020470d0120032802042101200341046a21030c010b0b2002417f6a220241014d04402000418004418008200241016b1b3602100b200020011060200441106a24000b9f0201057f2001044020002802042105200041106a2802002202200041146a280200220349044020022001ad2005ad422086843702002000200028021041086a36021020000f0b027f41002002200028020c22046b410375220641016a2202200320046b2203410275220420042002491b41ffffffff01200341037541ffffffff00491b2204450d001a200441037410400b2102200220064103746a22032001ad2005ad4220868437020020032000280210200028020c22066b22016b2105200220044103746a2102200341086a2103200141014e0440200520062001103c1a0b20002002360214200020033602102000200536020c20000f0b200041001002200028020422016a10d30141004100200120002802006a1003200010d20120000b2c01017f20002001280208200141016a20012d0000220041017122021b2001280204200041017620021b105d0bc80301087f230041c0016b22032400200341ac0810112105200341e8006a410210122104200341d8006a20051013200341c8006a20001013200341406b4100360200200341386a4200370300200341306a420037030020034200370328200341286a20032802582205200328025c101420032802482206200328024c101421072004200328022810152004200341d8006a10162004200341c8006a1016200428020c200441106a28020047044010000b2004280204210820042802002109200341106a1017210020034180016a200110182101200320023b018c01200341a8016a4100360200200341a0016a420037030020034198016a4200370300200342003703900120034190016a41001019200341b0016a20011018101a220220032f018c01101f2002410110192102200328029001210a200241046a101b2000200a101520004102101c20034190016a20011018101d220020032f018c011020200028020c200041106a28020047044010000b2009200820002802002000280204100d200028020c22010440200020013602100b200741046a101b200604402003200636024c0b200504402003200536025c0b200428020c22000440200420003602100b200341c0016a24000b0c0020002001ad4200105b1a0b0b0020002001ad4200105e0bf20301067f230041d0016b22052400200541086a419f0810112107200541f0006a410310122106200541e0006a20071013200541d0006a20001013200541c8006a4100360200200541406b4200370300200541386a420037030020054200370330200541306a2005280260220020052802641014200528025022072005280254101422082001101f2006200528023010152006200541e0006a10162006200541d0006a1016200620011020200628020c200641106a28020047044010000b200628020421092006280200210a200541186a1017210120054188016a20021018210220052004360298012005200336029401200541b8016a4100360200200541b0016a4200370300200541a8016a4200370300200542003703a001200541a0016a41001019200541c0016a20021018101a2203200528029401101f2003200528029801101f200341011019210320052802a0012104200341046a101b20012004101520014103101c200541a0016a20021018101d2201200528029401102020012005280298011020200128020c200141106a28020047044010000b200a200920012802002001280204100d200128020c22020440200120023602100b200841046a101b20070440200520073602540b20000440200520003602640b200628020c22010440200620013602100b200541d0016a24000b2e01017f230041206b22022400200241106a418d081011200241990810111010200020013a0010200241206a24000b3301017f230041206b22022400200241106a4180081011200241870810112001101e200041286a20013b0100200241206a24000b3701017f230041206b22022400200241106a4180081011200120024187081011200120011021200041406b2001360200200241206a24000b930201047f20002001470440200128020420012d00002202410176200241017122041b2102200141016a210320012802082105410a21012005200320041b210420002d0000410171220304402000280200417e71417f6a21010b200220014d0440027f2003044020002802080c010b200041016a0b210120020440200120042002104f0b200120026a41003a000020002d000041017104402000200236020420000f0b200020024101743a000020000f0b416f2103200141e6ffffff074d0440410b20014101742201200220022001491b220141106a4170712001410b491b21030b2003104022012004200210cc01200020023602042000200341017236020020002001360208200120026a41003a00000b20000b0d00200041b0016a20013a00000b0b00200041b0016a2c00000b23002000200110251a2000410c6a2001410c6a10251a200041186a200141186a10251a0b25002000200110181a2000410c6a2001410c6a10181a200041186a200141186a10181a20000b0d00200041c8026a20013a00000b0b00200041c8026a2c00000b9e0101047f2000200147044020012802042203200128020022026b41017522042000280208200028020022016b4101754d0440200041046a21052004200028020420016b41017522004b04402002200220004101746a2200200110541a200020032005104c0f0b200520022003200110543602000f0b2001044020004100360208200042003702000b2000200020041055105220022003200041046a104c0b0b3e01017f2000420037020020004100360208200128020420012802006b2202044020002002410175105220012802002001280204200041046a104c0b20000b3001027f200141046a21032001280200210203402002200346044020004188046a2001102f052002103021020c010b0b0be00201067f230041206b22042400024020002001460d00200141046a21062001280200210102402000280208450d00200028020021032000200041046a3602002000410036020820002802042102200041003602042002410036020820032802042202200320021b2102034020022203450d0120012006470440200341106a200141106a102521072003411c6a2001411c6a10251a024020032802082202450440410021020c010b2003200228020022054604402002410036020020022802042205450d012005104921020c010b200241003602042005450d002005104921020b2000200441106a2007104a2107200020042802102007200310452001103021010c010b0b0340200328020822030d000b200621010b034020012006460d01200441106a2000200141106a105020002004410c6a2004280210220341106a104a21022000200428020c2002200310452001103021010c000b000b200441206a24000b3601017f024020002802042201044003402001220028020022010d000c020b000b0340200020002802082200280200470d000b0b20000bd60101067f230041106b22022400200042003702042000200041046a2203360200200141046a21062001280200210103402001200646450440200141106a21050240027f027f0240024020032000280200460440200321040c010b20031041220441106a20051042450d010b20032802004504402002200336020c2003210420030c030b2002200436020c200441046a0c010b20002002410c6a200510430b22042802000d01200228020c0b21072002200020051050200020072004200228020010450b2001103021010c010b0b200241106a240020000b2300200041d0016a200110251a20004198016a20033a0000200041f8026a20023602000b920101047f2000200147044020012802042203200128020022026b22042000280208200028020022016b4d0440200041046a21052004200028020420016b22004b04402002200020026a22002001104d1a200020032005104c0f0b2005200220032001104d3602000f0b2001044020004100360208200042003702000b200020002004104e104b20022003200041046a104c0b0b3b01017f2000420037020020004100360208200128020420012802006b2202044020002002104b20012802002001280204200041046a104c0b20000b2601017f0340200241f800470440200020026a200120026a10251a2002410c6a21020c010b0b0b2301017f0340200020026a200120026a10181a2002410c6a220241f800470d000b20000b13002000200110251a2000200128020c36020c0b15002000200110181a2000200128020c36020c20000b3001027f200141046a210320012802002102034020022003460440200041f8066a2001103a052002103021020c010b0b0bd30201067f230041206b22042400024020002001460d00200141046a21062001280200210102402000280208450d00200028020021032000200041046a3602002000410036020820002802042102200041003602042002410036020820032802042202200320021b2102034020022203450d0120012006470440200341106a200141106a10252107024020032802082202450440410021020c010b2003200228020022054604402002410036020020022802042205450d012005104921020c010b200241003602042005450d002005104921020b2000200441106a2007104a2107200020042802102007200310452001103021010c010b0b0340200328020822030d000b200621010b034020012006460d01200441106a2000200141106a104420002004410c6a2004280210220341106a104a21022000200428020c2002200310452001103021010c000b000b200441206a24000bd60101067f230041106b22022400200042003702042000200041046a2203360200200141046a21062001280200210103402001200646450440200141106a21050240027f027f0240024020032000280200460440200321040c010b20031041220441106a20051042450d010b20032802004504402002200336020c2003210420030c030b2002200436020c200441046a0c010b20002002410c6a200510430b22042802000d01200228020c0b21072002200020051044200020072004200228020010450b2001103021010c010b0b200241106a240020000bfc0801067f03400240200020046a2105200120046a210320022004460d002003410371450d00200520032d00003a0000200441016a21040c010b0b200220046b210602402005410371220745044003402006411049450440200020046a2203200120046a2205290200370200200341086a200541086a290200370200200441106a2104200641706a21060c010b0b027f2006410871450440200120046a2103200020046a0c010b200020046a2205200120046a2204290200370200200441086a2103200541086a0b21042006410471044020042003280200360200200341046a2103200441046a21040b20064102710440200420032f00003b0000200341026a2103200441026a21040b2006410171450d01200420032d00003a000020000f0b024020064120490d002007417f6a220741024b0d00024002400240024002400240200741016b0e020102000b2005200120046a220328020022073a0000200541016a200341016a2f00003b0000200041036a2108200220046b417d6a2106034020064111490d03200420086a2203200120046a220541046a2802002202410874200741187672360200200341046a200541086a2802002207410874200241187672360200200341086a2005410c6a28020022024108742007411876723602002003410c6a200541106a2802002207410874200241187672360200200441106a2104200641706a21060c000b000b2005200120046a220328020022073a0000200541016a200341016a2d00003a0000200041026a2108200220046b417e6a2106034020064112490d03200420086a2203200120046a220541046a2802002202411074200741107672360200200341046a200541086a2802002207411074200241107672360200200341086a2005410c6a28020022024110742007411076723602002003410c6a200541106a2802002207411074200241107672360200200441106a2104200641706a21060c000b000b2005200120046a28020022073a0000200041016a21082004417f7320026a2106034020064113490d03200420086a2203200120046a220541046a2802002202411874200741087672360200200341046a200541086a2802002207411874200241087672360200200341086a2005410c6a28020022024118742007410876723602002003410c6a200541106a2802002207411874200241087672360200200441106a2104200641706a21060c000b000b200120046a41036a2103200020046a41036a21050c020b200120046a41026a2103200020046a41026a21050c010b200120046a41016a2103200020046a41016a21050b20064110710440200520032d00003a00002005200328000136000120052003290005370005200520032f000d3b000d200520032d000f3a000f200541106a2105200341106a21030b2006410871044020052003290000370000200541086a2105200341086a21030b2006410471044020052003280000360000200541046a2105200341046a21030b20064102710440200520032f00003b0000200541026a2105200341026a21030b2006410171450d00200520032d00003a00000b20000b2b01027f200141046a210203402002280200220341046a210220012003470d000b200041a80b6a2001103e0bbe0201057f024020002001460d00200041046a2102200141046a21030340200228020021020240027f4101200328020022032001460d001a20002002470d0141000b210402402000200246044020040d044114104022054100360200200541086a200341086a10181a20052104410121060340200120032802042203460d0241141040220241086a200341086a10181a2002200436020020042002360204200641016a2106200221040c000b000b200228020022032000280200220128020436020420012802042003360200034020002002460d0420002000280208417f6a360208200228020421020c000b000b2000280200220220053602042005200236020020002004360200200420003602042000200028020820066a3602080c020b200241086a200341086a10251a200241046a2102200341046a21030c000b000b0b840101037f200041003602082000200036020420002000360200200141046a2102037f20022802002203200146047f2000054114104022024100360200200241086a200341086a10181a20022000360204200028020021042000200236020020022004360200200420023602042000200028020841016a360208200341046a21020c010b0b0b0b002000410120001b10670b3e01027f024020002802002201044003402001220228020422010d000c020b000b03402000280208220228020020004621012002210020010d000b0b20020bb20101067f02400240200128020420012d00002202410176200241017122031b2205200028020420002d00002202410176200241017122041b2206200520064922071b2202450d002000280208200041016a20041b21002001280208200141016a20031b210103402002450d0120002d0000220320012d00002204460440200141016a2101200041016a21002002417f6a21020c010b0b200320046b22020d010b417f200720062005491b21020b2002411f760b890101027f200041046a2103024020002802042200044002400340024002402002200041106a220410420440200028020022040d012001200036020020000f0b200420021042450d03200041046a210320002802042204450d01200321000b20002103200421000c010b0b2001200036020020030f0b200120003602000c010b200120033602000b20030b2d01017f2000411c104022033602002000200141046a360204200341106a200210181a200041086a41013a00000b480020032001360208200342003702002002200336020020002802002802002201044020002001360200200228020021030b2000280204200310462000200028020841016a3602080bec0101037f200120002001463a000c03400240024020002001460d00200128020822022d000c0d002002200228020822032802002204460440024020032802042204450d0020042d000c0d002004410c6a21010c030b20012002280200470440200210472002280208220228020821030b200241013a000c200341003a000c200310480f0b02402004450d0020042d000c0d002004410c6a21010c020b20012002280200460440200210482002280208220228020821030b200241013a000c200341003a000c200310470b0f0b200241013a000c200320002003463a000c200141013a0000200321010c000b000b5101027f200020002802042201280200220236020420020440200220003602080b200120002802083602082000280208220220022802002000474102746a200136020020002001360208200120003602000b5101027f200020002802002201280204220236020020020440200220003602080b200120002802083602082000280208220220022802002000474102746a200136020020002001360208200120003602040b1d01017f03402000220128020022000d00200128020422000d000b20010b5c01017f0240200028020422030440034002402002200341106a1042044020032802002200450d040c010b200328020422000d0020012003360200200341046a0f0b200021030c000b000b200041046a21030b2001200336020020030b2001017f2000200110402202360200200020023602042000200120026a3602080b2800200120006b220141014e0440200228020020002001103c1a2002200228020020016a3602000b0b1900200120006b22010440200220002001104f0b200120026a0b2e01017f2001200028020820002802006b2200410174220220022001491b41ffffffff07200041ffffffff03491b0b8d0301037f024020002001460d00200120006b20026b410020024101746b4d0440200020012002103c1a0c010b20002001734103712103027f024020002001490440200020030d021a410021030340200120036a2105200020036a2204410371450440200220036b210241002103034020024104490d04200320046a200320056a280200360200200341046a21032002417c6a21020c000b000b20022003460d04200420052d00003a0000200341016a21030c000b000b024020030d002001417f6a21040340200020026a22034103714504402001417c6a21032000417c6a2104034020024104490d03200220046a200220036a2802003602002002417c6a21020c000b000b2002450d042003417f6a200220046a2d00003a00002002417f6a21020c000b000b2001417f6a210103402002450d03200020026a417f6a200120026a2d00003a00002002417f6a21020c000b000b200320056a2101200320046a0b210303402002450d01200320012d00003a00002002417f6a2102200341016a2103200141016a21010c000b000b0b2c01017f20004128104022033602002000200141046a360204200341106a20021051200041086a41013a00000b16002000200110181a2000410c6a2001410c6a10181a0b2301017f2000200110532202360200200020023602042000200220014101746a3602080b0900200041017410400b2501017f200120006b2201410175210320010440200220002001104f0b200220034101746a0b2a002001200028020820002802006b220020002001491b41ffffffff07200041017541ffffffff03491b0b5b01027f02402002410a4d0440200020024101743a0000200041016a21030c010b200241106a4170712204104021032000200236020420002004410172360200200020033602080b20032001200210cc01200220036a41003a00000b1600200041003602082000420037020020004100105c0bdd0101047f024020002802042203200028020022026b22042001490440200028020820036b200120046b22024f04400340200341003a00002000200028020441016a22033602042002417f6a22020d000c030b000b20002001104e220104402001104021050b200420056a220421030340200341003a0000200341016a21032002417f6a22020d000b200120056a210520042000280204200028020022046b22016b2102200141014e0440200220042001103c1a0b2000200536020820002003360204200020023602000f0b200420014d0d002000200120026a3602040b0b1e01017f03402000044020004108762100200141016a21010c010b0b20010b25002000200120026a417f6a220241087641fcffff07716a280200200241ff07714102746a0b900101027f4101210420014280015441002002501b450440034020012002845045044020024238862001420888842101200341016a2103200242088821020c010b0b200341384f047f2003105920036a0520030b41016a21040b027f200041186a28020022030440200041086a280200200041146a2802002003105a0c010b20000b2203200328020020046a36020020000b2f01017f200028020820014904402001106720002802002000280204103c210220002001360208200020023602000b0b2c01017f2000200120021004200028020422036a10d30120012002200320002802006a1005200010d20120000b2a01017f2000200220011006200028020422036a10d30120022001200320002802006a1007200010d2010b2801017f200028020820002802046b2201410874417f6a410020011b200028021420002802106a6b0b2501017f200028020821020340200120024645044020002002417c6a22023602080c010b0b0ba10202057f017e230041206b22052400024020002802082202200028020c2203470d0020002802042204200028020022064b04402000200420022004200420066b41027541016a417e6d41027422036a106222023602082000200028020420036a3602040c010b200541086a200320066b2202410175410120021b220220024102762000410c6a10632103200028020821042000280204210203402002200446450440200328020820022802003602002003200328020841046a360208200241046a21020c010b0b20002902002107200020032902003702002003200737020020002902082107200020032902083702082003200737020820031064200028020821020b200220012802003602002000200028020841046a360208200541206a24000b2501017f200120006b2201410275210320010440200220002001104f0b200220034102746a0b4f01017f2000410036020c200041106a2003360200200104402001410274104021040b200020043602002000200420024102746a22023602082000200420014102746a36020c2000200236020420000b2b01027f200028020821012000280204210203402001200247044020002001417c6a22013602080c010b0b0b1b00200120006b22010440200220016b220220002001104f0b20020b4f01037f20012802042203200128021020012802146a220441087641fcffff07716a21022000027f410020032001280208460d001a2002280200200441ff07714102746a0b360204200020023602000b9b0101047f230041106b220124002001200036020c2000047f41880c200041086a2202411076220041880c2802006a220336020041840c41840c280200220420026a41076a417871220236020002400240200341107420024d044041880c200341016a360200200041016a21000c010b2000450d010b200040000d0010000b20042001410c6a4104103c41086a0541000b2100200141106a240020000b090010cb011069106a0be82602057f027e230041c0166b2201240010082200106722021009200141d00a6a200141086a20022000106b22004100106c02400240200141d00a6a106d2205500d0041c208106e20055104402000106f200141d00a6a107010710c020b41c708106e200551044020001072410247044010000b200141d00a6a20004101106c200141d00a6a10732100200141d00a6a1070220220001022200210710c020b41d008106e20055104402000106f200141d00a6a107022032d00102102200141b8086a10172200200210741015200020021020200028020c200041106a28020047044010000b20002802002000280204100e200028020c22020440200020023602100b200310710c020b41d908106e200551044020001072410247044010000b200141d00a6a20004101106c200141d00a6a10752100200141d00a6a1070220220001023200210710c020b41e308106e20055104402000106f200141d00a6a1070220341286a2f01002102200141b8086a10172200200210761015200020021020200028020c200041106a28020047044010000b20002802002000280204100e200028020c22020440200020023602100b200310710c020b41ed08106e200551044020001072410247044010000b200141d00a6a20004101106c200141d00a6a10772100200141d00a6a1070220220001024200210710c020b41f708106e20055104402000106f200141d00a6a1070220341406b2802002102200141b8086a10172200200210781015200020021020200028020c200041106a28020047044010000b20002802002000280204100e200028020c22020440200020023602100b200310710c020b418109106e200551044020001072410247044010000b200141d00a6a20004101106c200141d00a6a106d2105200141d00a6a1070220041d8006a2005370300200010710c020b418b09106e20055104402000106f200141d00a6a1070220241d8006a2903002105200141b8086a1017220020051079101520002005107a200028020c200041106a28020047044010000b20002802002000280204100e200028020c22030440200020033602100b200210710c020b419509106e2005510440200141b8066a107b210220001072410247044010000b200141d00a6a20004101106c200141d00a6a2002107c200141d00a6a1070220041f8006a200141b8086a2002101810251a200010710c020b419f09106e20055104402000106f200141a0046a200141d00a6a1070220241f8006a10182100200141b8086a101722032000107d10152003200141b8066a20001018101d220028020c200041106a28020047044010000b20002802002000280204100e200028020c22030440200020033602100b200210710c020b41a909106e2005510440200141003a00b80820001072410247044010000b200141d00a6a20004101106c200141d00a6a200141b8086a107e200141d00a6a107022004198016a20012d00b8083a0000200010710c020b41b109106e20055104402000106f200141d00a6a107022034198016a2d00002102200141b8086a10172200200210741015200020021020200028020c200041106a28020047044010000b20002802002000280204100e200028020c22020440200020023602100b200310710c020b41b909106e200551044020004101107f0c020b41c109106e2005510440200041021080010c020b41c909106e2005510440200141b8066a10810120001072410247044010000b200141d00a6a20004101106c200141d00a6a200141b8066a108201200141d00a6a1070220041d0016a200141b8086a200141b8066a101810251a200010710c020b41d409106e20055104402000106f200141b8066a200141d00a6a1070220241d0016a10181a200141b8086a10172200200141b8066a10830110152000200141b8066a108401200028020c200041106a28020047044010000b20002802002000280204100e200028020c22030440200020033602100b200210710c020b41df09106e2005510440200141b8066a41241085011a200141b8066a108601210220001072410247044010000b200141d00a6a20004101106c200141d00a6a2002108701200141d00a6a107022004190026a200141b8086a200210291028200010710c020b41ec09106e20055104402000106f200141b8086a200141d00a6a107022034190026a10292102200141b8066a101722002002108801101520002002108901200028020c200041106a28020047044010000b20002802002000280204100e200028020c22020440200020023602100b200310710c020b41f909106e200551044020004103107f0c020b41810a106e2005510440200041041080010c020b41890a106e200551044020001072410247044010000b200141d00a6a20004101106c200141d00a6a108a012100200141d00a6a1070220241e0026a20003b0100200210710c020b41920a106e20055104402000106f200141d00a6a1070220341e0026a2e01002102200141b8086a101722002002108b01101520002002108c01200028020c200041106a28020047044010000b20002802002000280204100e200028020c22020440200020023602100b200310710c020b419b0a106e200551044020001072410247044010000b200141d00a6a20004101106c200141d00a6a108d012100200141d00a6a1070220241f8026a2000360200200210710c020b41a40a106e20055104402000106f200141d00a6a1070220341f8026a2802002102200141b8086a101722002002108e01101520002002108c01200028020c200041106a28020047044010000b20002802002000280204100e200028020c22020440200020023602100b200310710c020b41ad0a106e200551044020001072410247044010000b200141d00a6a20004101106c200141d00a6a108f012105200141d00a6a107022004190036a2005370300200010710c020b41b60a106e20055104402000106f200141d00a6a107022024190036a2903002105200141b8086a101722002005109001101520002005109101200028020c200041106a28020047044010000b20002802002000280204100e200028020c22030440200020033602100b200210710c020b41bf0a106e2005510440200141003602c006200142003703b80620001072410247044010000b200141d00a6a20004101106c200141d00a6a200141b8066a109201200141d00a6a1070220241e0036a200141b8086a200141b8066a102d2200102c200028020022030440200020033602040b2002107120012802b8062200450d02200120003602bc060c020b41c90a106e20055104402000106f200141b8066a200141d00a6a1070220341e0036a102d2102200141b8086a101722002002109301101520002002109401200028020c200041106a28020047044010000b20002802002000280204100e200028020c22040440200020043602100b200228020022000440200220003602040b200310710c020b41d30a106e2005510440200142003702bc062001200141b8066a4104723602b80620001072410247044010000b200141d00a6a20004101106c200141d00a6a200141b8066a109501200141d00a6a10702200200141b8086a200141b8066a1031102e200010710c020b41da0a106e20055104402000106f200141b8066a200141d00a6a107022034188046a10312102200141b8086a101722002002109601101520002002109701200028020c200041106a28020047044010000b20002802002000280204100e200028020c22020440200020023602100b200310710c020b41e10a106e2005510440200141b8086a108101200141003a00c808200141003602c408200141c8086a210220001072410447044010000b200141d00a6a20004101106c200141d00a6a200141b8086a108201200141d00a6a20004102106c2001200141d00a6a108d013602c408200141d00a6a20004103106c200141d00a6a2002107e200141d00a6a10702100200141b8066a200141b8086a10181a2000200141b8066a20012802c40820012d00c8081032200010710c020b41f10a106e2005510440200141003602a804200142003703a00420001072410247044010000b200141d00a6a20004101106c200141d00a6a200141a0046a109801200141d00a6a1070220341b0046a200141b8086a200141b8066a200141a0046a10342200103422021033200228020022040440200220043602040b200028020022020440200020023602040b2003107120012802a0042200450d02200120003602a4040c020b41fa0a106e20055104402000106f200141b8066a200141d00a6a1070220341b0046a10342102200141b8086a10172200200228020020022802041099011015200020021016200028020c200041106a28020047044010000b20002802002000280204100e200028020c22040440200020043602100b200228020022000440200220003602040b200310710c020b41830b106e2005510440200141b8066a41f8001085011a200141b8066a109a01210220001072410247044010000b200141d00a6a20004101106c200141d00a6a2002109b01200141d00a6a1070220041c0056a200141b8086a200210361035200010710c020b418c0b106e20055104402000106f200141b8086a200141d00a6a1070220341c0056a10362102200141b8066a101722002002109c01101520002002109d01200028020c200041106a28020047044010000b20002802002000280204100e200028020c22020440200020023602100b200310710c020b41950b106e2005510440200141b8066a109e01210220001072410247044010000b200141d00a6a20004101106c200141d00a6a2002109f01200141d00a6a1070220041d0066a200141b8086a200210381037200010710c020b419d0b106e20055104402000106f200141b8066a200141d00a6a1070220341d0066a10382102200141b8086a10172200200210a00110152000200210a101200028020c200041106a28020047044010000b20002802002000280204100e200028020c22020440200020023602100b200310710c020b41a50b106e2005510440200142003702bc062001200141b8066a4104723602b80620001072410247044010000b200141d00a6a20004101106c200141d00a6a200141b8066a10a201200141d00a6a10702200200141b8086a200141b8066a103b1039200010710c020b41ac0b106e20055104402000106f200141b8066a200141d00a6a1070220341f8066a103b2102200141b8086a10172200200210a30110152000200210a401200028020c200041106a28020047044010000b20002802002000280204100e200028020c22020440200020023602100b200310710c020b41b30b106e2005510440200141b8066a4180021085011a20001072410247044010000b200141d00a6a20004101106c200141d00a6a200141b8066a10a501200141d00a6a10702100200141206a200141b8066a418002103c1a200141b8086a200141206a418002103c1a20004190096a200141b8086a418002103c1a200010710c020b41c00b106e20055104402000106f200141a0026a200141d00a6a107022024190096a418002103c1a200141a0066a10172200200141a0026a10a6011015200141a0046a200141a0026a418002103c1a200141b8066a200141a0046a418002103c1a200141206a200141b8066a418002103c1a200141b8086a200141206a418002103c1a2000200141b8086a418002105d220028020c200041106a28020047044010000b20002802002000280204100e200028020c22030440200020033602100b200210710c020b41cd0b106e2005510440200141003602c0062001200141b8066a3602bc062001200141b8066a3602b80620001072410247044010000b200141d00a6a20004101106c200141d00a6a200141b8066a10a701200141d00a6a10702200200141b8086a200141b8066a103f2202103d200210a80120001071200141b8066a10a8010c020b41d50b106e20055104402000106f200141b8066a200141d00a6a1070220341a80b6a103f2102200141b8086a10172200200210a90110152000200210aa01200028020c200041106a28020047044010000b20002802002000280204100e200028020c22040440200020043602100b200210a801200310710c020b41dd0b106e2005510440200141c8086a22024100360200200141c0086a22034200370300200142003703b80820001072410247044010000b200141d00a6a20004101106c200141d00a6a200141b8086a10ab01200141d00a6a10702100200141b0066a20022802002202360200200141a8066a20032903002205370300200120012903b80822063703a006200041d80b6a2006370300200041e00b6a2005370300200041e80b6a2002360200200010710c020b41e80b106e2005520d002000106f200141306a2200200141d00a6a1070220241e80b6a280000360200200141286a2203200241e00b6a2900003703002001200241d80b6a290000370320200141b8086a10172204200141206a10ac011015200141b0026a20002802002200360200200141a8026a200329030022053703002001200129032022063703a002200141a8046a2005370300200141b0046a2000360200200141a8066a2005370300200141b0066a2000360200200120063703a004200120063703a006200141c8066a2000360200200141c0066a2005370300200120063703b8062004200141b8066a4114105d220028020c200041106a28020047044010000b20002802002000280204100e200028020c22030440200020033602100b200210710c010b10000b200141c0166a24000b880101037f41f40b410136020041f80b2802002100034020000440034041fc0b41fc0b2802002201417f6a2202360200200141014845044041f40b4100360200200020024102746a22004184016a280200200041046a28020011030041f40b410136020041f80b28020021000c010b0b41fc0b412036020041f80b200028020022003602000c010b0b0b0d00200020012002411c10ad010bd00202067f017e230041106b220324002001280208220520024b0440200341086a200110d10120012003280208200328020c10cf0136020c2003200110d101410021052001027f410020032802002207450d001a410020032802042208200128020c2206490d001a200820062006417f461b210420070b360210200141146a2004360200200141003602080b200141106a210603402001280214210402402005200249044020040d01410021040b200020062802002004411410ad011a200341106a24000f0b2003200110d10141002104027f410020032802002205450d001a410020032802042208200128020c2207490d001a200820076b2104200520076a0b210520012004360214200120053602102003200641002005200410cf0110d0012001200329030022093702102001200128020c2009422088a76a36020c2001200128020841016a22053602080c000b000b880102027f017e230041106b22012400200010ae0102400240200010af01450d002000280204450d0020002802002d000041c001490d010b10000b200141086a200010b001200128020c220041094f044010000b200128020821020340200004402000417f6a210020023100002003420886842103200241016a21020c010b0b200141106a240020030b3901027e42a5c688a1c89ca7f94b210103402000300000220250450440200041016a2100200142b383808080207e20028521010c010b0b20010b0e0020001072410147044010000b0bf42901097f230041406a22012400200042ddbe888dc5fcfca4987f370308200041003a0000200141286a101722032000290308107a200328020c200341106a28020047044010000b02402003280200220720032802042208100a2205450d002001410036022020014200370318200141186a200510582007200820012802182202200128021c220620026b100b417f47044020002001200241016a20062002417f736a106b10733a0010200521040b2002450d002001200236021c0b200328020c22020440200320023602100b2004450440200020002d00003a00100b41002104200041003b0118200041206a220242debe888dc5fcfca4987f370300200141286a101722032002290300107a200328020c200341106a28020047044010000b02402003280200220720032802042208100a2205450d002001410036022020014200370318200141186a200510582007200820012802182202200128021c220620026b100b417f47044020002001200241016a20062002417f736a106b10753b0128200521040b2002450d002001200236021c0b200328020c22020440200320023602100b2004450440200020002f01183b01280b4100210420004100360230200041386a220242dfbe888dc5fcfca4987f370300200141286a101722032002290300107a200328020c200341106a28020047044010000b02402003280200220720032802042208100a2205450d002001410036022020014200370318200141186a200510582007200820012802182202200128021c220620026b100b417f47044020002001200241016a20062002417f736a106b1077360240200521040b2002450d002001200236021c0b200328020c22020440200320023602100b2004450440200020002802303602400b20004200370348200041d0006a220442d9be888dc5fcfca4987f370300200141286a101722032004290300107a200328020c200341106a28020047044010000b02402003280200220720032802042208100a2205450440410021020c010b410021022001410036022020014200370318200141186a200510582007200820012802182204200128021c220620046b100b417f47044020002001200441016a20062004417f736a106b106d370358200521020b2004450d002001200436021c0b200328020c22040440200320043602100b2002450440200020002903483703580b200041e0006a107b2109200041f0006a220442a7cea8ad82a0ff995b370300200041f8006a107b2107200141286a101722032004290300107a200328020c200341106a28020047044010000b02402003280200220820032802042206100a2205450440410021020c010b410021022001410036022020014200370318200141186a200510582008200620012802182204200128021c220620046b100b417f4704402001200441016a20062004417f736a106b2007107c200521020b2004450d002001200436021c0b200328020c22040440200320043602100b20024504402007200910251a0b41002104200041003a00880120004190016a220242f4a2efb3f6e5b8ad03370300200141286a101722032002290300107a200328020c200341106a28020047044010000b02402003280200220720032802042208100a2205450d002001410036022020014200370318200141186a200510582007200820012802182202200128021c220620026b100b417f4704402001200241016a20062002417f736a106b20004198016a107e200521040b2002450d002001200236021c0b200328020c22020440200320023602100b2004450440200020002d0088013a0098010b200041003a00a001200041a8016a220342badda0b2f6c5fa8e033703002003200041b0016a10b101450440200020002d00a0013a00b0010b200042003703b801200041c0016a4100360200200041b8016a107b2109200041c8016a2204428aedabfdf7a698fe29370300200041d0016a2207107b1a200141286a101722032004290300107a200328020c200341106a28020047044010000b02402003280200220820032802042206100a2205450440410021020c010b410021022001410036022020014200370318200141186a200510582008200620012802182204200128021c220620046b100b417f4704402001200441016a20062004417f736a106b2007108201200521020b2004450d002001200436021c0b200328020c22040440200320043602100b20024504402007200910251a0b41002104200041e0016a4124108501108601210920004188026a220242d4b7b1edebf7e3f66a37030020004190026a1086012107200141286a101722032002290300107a200328020c200341106a28020047044010000b02402003280200220820032802042206100a2205450d002001410036022020014200370318200141186a200510582008200620012802182202200128021c220620026b100b417f4704402001200241016a20062002417f736a106b2007108701200521040b2002450d002001200236021c0b200328020c22020440200320023602100b20044504402007200910280b200041003a00b802200041c0026a220342ccacbdb4f8a587a93d3703002003200041c8026a10b101450440200020002d00b8023a00c8020b200041003b01d002200041d8026a220442cfacbdb4f8a587a93d370300200141286a101722032004290300107a200328020c200341106a28020047044010000b02402003280200220720032802042208100a2205450440410021020c010b410021022001410036022020014200370318200141186a200510582007200820012802182204200128021c220620046b100b417f47044020002001200441016a20062004417f736a106b108a013b01e002200521020b2004450d002001200436021c0b200328020c22040440200320043602100b2002450440200020002f01d0023b01e0020b41002104200041003602e802200041f0026a220242ceacbdb4f8a587a93d370300200141286a101722032002290300107a200328020c200341106a28020047044010000b02402003280200220720032802042208100a2205450d002001410036022020014200370318200141186a200510582007200820012802182202200128021c220620026b100b417f47044020002001200241016a20062002417f736a106b108d013602f802200521040b2002450d002001200236021c0b200328020c22020440200320023602100b2004450440200020002802e8023602f8020b200042003703800320004188036a220442c8acbdb4f8a587a93d370300200141286a101722032004290300107a200328020c200341106a28020047044010000b02402003280200220720032802042208100a2205450440410021020c010b410021022001410036022020014200370318200141186a200510582007200820012802182204200128021c220620046b100b417f47044020002001200441016a20062004417f736a106b108f0137039003200521020b2004450d002001200436021c0b200328020c22040440200320043602100b20024504402000200029038003370390030b410021042000410036029803200041a0036a220242e2e780dbeae4fcabe100370300200141286a101722032002290300107a200328020c200341106a28020047044010000b02402003280200220720032802042208100a2205450d002001410036022020014200370318200141186a200510582007200820012802182202200128021c220620026b100b417f47044020002001200241016a20062002417f736a106b10773602a803200521040b2002450d002001200236021c0b200328020c22020440200320023602100b200445044020002000280298033602a8030b200042003703b003200041b8036a220442b3debf9dbddf9ca832370300200141286a101722032004290300107a200328020c200341106a28020047044010000b02402003280200220720032802042208100a2205450440410021020c010b410021022001410036022020014200370318200141186a200510582007200820012802182204200128021c220620046b100b417f47044020002001200441016a20062004417f736a106b106d3703c003200521020b2004450d002001200436021c0b200328020c22040440200320043602100b2002450440200020002903b0033703c0030b200042003702c80341002104200041e8036a4100360200200041e0036a22074200370200200041d8036a2202429fe6c89bc186c5be1d370300200041d0036a4100360200200141286a101722032002290300107a200328020c200341106a28020047044010000b02402003280200220820032802042206100a2205450d002001410036022020014200370318200141186a200510582008200620012802182202200128021c220920026b100b417f4704402001200241016a20092002417f736a106b2007109201200521040b2002450d002001200236021c0b200328020c22020440200320023602100b20044504402007200041c8036a102c0b200041f4036a220342003702002000418c046a2204420037020020004180046a2202428cbcadf0bacdb08975370300200020033602f00320004188046a22072004360200200141286a101722032002290300107a200328020c200341106a28020047044010000b02402003280200220820032802042206100a2205450440410021020c010b410021022001410036022020014200370318200141186a200510582008200620012802182204200128021c220920046b100b417f4704402001200441016a20092004417f736a106b2007109501200521020b2004450d002001200436021c0b200328020c22040440200320043602100b20024504402007200041f0036a102f0b200042003702980441002104200041b8046a4100360200200041b0046a22074200370200200041a8046a220242bd8ce2969cacfba4b07f370300200041a0046a4100360200200141286a101722032002290300107a200328020c200341106a28020047044010000b02402003280200220820032802042206100a2205450d002001410036022020014200370318200141186a200510582008200620012802182202200128021c220920026b100b417f4704402001200241016a20092002417f736a106b2007109801200521040b2002450d002001200236021c0b200328020c22020440200320023602100b2004450440200720004198046a10330b41002104200041c0046a41f800108501109a012109200041b8056a2202429fa88ce0a0829ecea47f370300200041c0056a109a012107200141286a101722032002290300107a200328020c200341106a28020047044010000b02402003280200220820032802042206100a2205450d002001410036022020014200370318200141186a200510582008200620012802182202200128021c220620026b100b417f4704402001200241016a20062002417f736a106b2007109b01200521040b2002450d002001200236021c0b200328020c22020440200320023602100b20044504402007200910350b200041b8066a109e012109200041c8066a220442bcf8d4f484c7a18d807f370300200041d0066a109e012107200141286a101722032004290300107a200328020c200341106a28020047044010000b02402003280200220820032802042206100a2205450440410021020c010b410021022001410036022020014200370318200141186a200510582008200620012802182204200128021c220620046b100b417f4704402001200441016a20062004417f736a106b2007109f01200521020b2004450d002001200436021c0b200328020c22040440200320043602100b20024504402007200910370b200041e4066a22034200370200200041fc066a22044200370200200041f0066a220242eafdbbb690ac81edca00370300200020033602e006200041f8066a22072004360200200141286a101722032002290300107a200328020c200341106a28020047044010000b02402003280200220820032802042206100a2205450440410021020c010b410021022001410036022020014200370318200141186a200510582008200620012802182204200128021c220920046b100b417f4704402001200441016a20092004417f736a106b200710a201200521020b2004450d002001200436021c0b200328020c22040440200320043602100b20024504402007200041e0066a103a0b4100210420004188076a418002108501210920004188096a220242d0b4afbcbf988ce0b77f37030020004190096a4180021085012107200141286a101722032002290300107a200328020c200341106a28020047044010000b02402003280200220820032802042206100a2205450d002001410036022020014200370318200141186a200510582008200620012802182202200128021c220620026b100b417f4704402001200241016a20062002417f736a106b200710a501200521040b2002450d002001200236021c0b200328020c22020440200320023602100b200445044020072009418002103c1a0b41002102200041b00b6a4100360200200041ac0b6a200041a80b6a2204360200200041a00b6a220542f4ffce959b97c9c1d500370300200041980b6a4100360200200041940b6a200041900b6a2207360200200020073602900b20042004360200200141286a101722032005290300107a200328020c200341106a28020047044010000b02402003280200220620032802042209100a2208450d002001410036022020014200370318200141186a200810582006200920012802182205200128021c220620056b100b417f4704402001200541016a20062005417f736a106b200410a701200821020b2005450d002001200536021c0b200328020c22050440200320053602100b200245044020042007103e0b200042003700b80b41002104200041c80b6a4100360000200041c00b6a4200370000200041d80b6a22054200370000200041d00b6a220242affad78bbfdecaa6f300370300200041e00b6a4200370000200041e80b6a4100360000200141286a101722032002290300107a200328020c200341106a28020047044010000b02402003280200220820032802042206100a2207450d002001410036022020014200370318200141186a200710582008200620012802182202200128021c220920026b100b417f4704402001200241016a20092002417f736a106b200510ab01200721040b2002450d002001200236021c0b200328020c22020440200320023602100b20044504402005200041b80b6a2203290300370300200541106a200341106a280200360200200541086a200341086a2903003703000b200141406b240020000b973102087f027e230041c0086b22052400200541c0066a10172201200041d00b6a22022903001079101520012002290300107a200041d80b6a2102200128020c200141106a28020047044010000b2001280204210720012802002106200541c0046a10172104200210ac012108200420054180026a10b201220310b3012004200820032802046a20032802006b1015200541a0026a200241106a280000220836020020054198026a200241086a290000220937030020052002290000220a37039002200541b0026a2009370300200541b8026a2008360200200541086a2009370300200541106a20083602002005200a3703a8022005200a370300200541d0026a2008360200200541c8026a20093703002005200a3703c00202402004200541c0026a4114105d220228020c200241106a280200460440200241046a2104200228020021080c010b200241046a2104100020022802002108200228020c2002280210460d0010000b2006200720082004280200100c200328020022040440200320043602040b200228020c22030440200220033602100b200128020c22020440200120023602100b200541c0066a10172202200041a00b6a22012903001079101520022001290300107a200041a80b6a2104200228020c200241106a28020047044010000b2002280204210820022802002107200541c0046a10172101200410a90121062001200541c0026a10b201220310b3012001200620032802046a20032802006b10152001200410aa010240200128020c200141106a280200460440200141046a2104200128020021060c010b200141046a2104100020012802002106200128020c2001280210460d0010000b2007200820062004280200100c200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200041a80b6a10a801200041900b6a10a801200541a8026a1017220120004188096a22022903001079101520012002290300107a20004190096a2104200128020c200141106a28020047044010000b200128020421082001280200210720054190026a10172102200410a6012106200220054180026a10b201220310b3012002200620032802046a20032802006b101520052004418002103c220541c0026a2005418002103c1a200541c0046a200541c0026a418002103c1a200541c0066a200541c0046a418002103c1a02402002200541c0066a418002105d220228020c200241106a280200460440200241046a2104200228020021060c010b200241046a2104100020022802002106200228020c2002280210460d0010000b2007200820062004280200100c200328020022040440200320043602040b200228020c22030440200220033602100b200128020c22020440200120023602100b200541c0066a10172202200041f0066a22012903001079101520022001290300107a200041f8066a2104200228020c200241106a28020047044010000b2002280204210820022802002107200541c0046a10172101200410a30121062001200541c0026a10b201220310b3012001200620032802046a20032802006b10152001200410a4010240200128020c200141106a280200460440200141046a2104200128020021060c010b200141046a2104100020012802002106200128020c2001280210460d0010000b2007200820062004280200100c200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a10172202200041c8066a22012903001079101520022001290300107a200041d0066a2104200228020c200241106a28020047044010000b2002280204210820022802002107200541c0046a10172101200410a00121062001200541c0026a10b201220310b3012001200620032802046a20032802006b10152001200410a1010240200128020c200141106a280200460440200141046a2104200128020021060c010b200141046a2104100020012802002106200128020c2001280210460d0010000b2007200820062004280200100c200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a10172202200041b8056a22012903001079101520022001290300107a200041c0056a2104200228020c200241106a28020047044010000b2002280204210820022802002107200541c0046a101721012004109c0121062001200541c0026a10b201220310b3012001200620032802046a20032802006b101520012004109d010240200128020c200141106a280200460440200141046a2104200128020021060c010b200141046a2104100020012802002106200128020c2001280210460d0010000b2007200820062004280200100c200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a10172202200041a8046a22012903001079101520022001290300107a200041b0046a2104200228020c200241106a28020047044010000b2002280204210820022802002107200541c0046a1017210120002802b004200041b4046a28020010990121062001200541c0026a10b201220310b3012001200620032802046a20032802006b10152001200410160240200128020c200141106a280200460440200141046a2104200128020021060c010b200141046a2104100020012802002106200128020c2001280210460d0010000b2007200820062004280200100c200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200041b0046a28020022010440200041b4046a20013602000b200028029804220104402000419c046a20013602000b200541c0066a1017220220004180046a22012903001079101520022001290300107a20004188046a2104200228020c200241106a28020047044010000b2002280204210820022802002107200541c0046a10172101200410960121062001200541c0026a10b201220310b3012001200620032802046a20032802006b1015200120041097010240200128020c200141106a280200460440200141046a2104200128020021060c010b200141046a2104100020012802002106200128020c2001280210460d0010000b2007200820062004280200100c200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a10172202200041d8036a22012903001079101520022001290300107a200041e0036a2104200228020c200241106a28020047044010000b2002280204210820022802002107200541c0046a10172101200410930121062001200541c0026a10b201220310b3012001200620032802046a20032802006b1015200120041094010240200128020c200141106a280200460440200141046a2104200128020021060c010b200141046a2104100020012802002106200128020c2001280210460d0010000b2007200820062004280200100c200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200041e0036a28020022010440200041e4036a20013602000b20002802c80322010440200041cc036a20013602000b200541c0046a10172202200041b8036a22012903001079101520022001290300107a200228020c200241106a28020047044010000b2002280204210420022802002108200541c0026a10172101200541d8066a4100360200200541d0066a4200370300200541c8066a4200370300200542003703c006200541c0066a20002903c00310b40120052802c0062107200541c0066a410472101b2001200541c0066a10b201220310b3012001200720032802046a20032802006b1015200120002903c003107a0240200128020c200141106a280200460440200141046a2107200128020021060c010b200141046a2107100020012802002106200128020c2001280210460d0010000b2008200420062007280200100c200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0046a10172202200041a0036a22012903001079101520022001290300107a200228020c200241106a28020047044010000b2002280204210420022802002108200541c0026a10172101200541d8066a4100360200200541d0066a4200370300200541c8066a4200370300200542003703c006200541c0066a20002802a803101f20052802c0062107200541c0066a410472101b2001200541c0066a10b201220310b3012001200720032802046a20032802006b1015200120002802a80310200240200128020c200141106a280200460440200141046a2107200128020021060c010b200141046a2107100020012802002106200128020c2001280210460d0010000b2008200420062007280200100c200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a1017220220004188036a22012903001079101520022001290300107a200228020c200241106a28020047044010000b2002280204210420022802002108200541c0046a1017210120002903900310900121072001200541c0026a10b201220310b3012001200720032802046a20032802006b101520012000290390031091010240200128020c200141106a280200460440200141046a2107200128020021060c010b200141046a2107100020012802002106200128020c2001280210460d0010000b2008200420062007280200100c200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a10172202200041f0026a22012903001079101520022001290300107a200228020c200241106a28020047044010000b2002280204210420022802002108200541c0046a1017210120002802f802108e0121072001200541c0026a10b201220310b3012001200720032802046a20032802006b1015200120002802f802108c010240200128020c200141106a280200460440200141046a2107200128020021060c010b200141046a2107100020012802002106200128020c2001280210460d0010000b2008200420062007280200100c200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a10172202200041d8026a22012903001079101520022001290300107a200228020c200241106a28020047044010000b2002280204210420022802002108200541c0046a1017210120002f01e002108b0121072001200541c0026a10b201220310b3012001200720032802046a20032802006b1015200120002e01e002108c010240200128020c200141106a280200460440200141046a2107200128020021060c010b200141046a2107100020012802002106200128020c2001280210460d0010000b2008200420062007280200100c200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200041c0026a200041c8026a10b501200541c0066a1017220220004188026a22012903001079101520022001290300107a20004190026a2104200228020c200241106a28020047044010000b2002280204210820022802002107200541c0046a10172101200410880121062001200541c0026a10b201220310b3012001200620032802046a20032802006b1015200120041089010240200128020c200141106a280200460440200141046a2104200128020021060c010b200141046a2104100020012802002106200128020c2001280210460d0010000b2007200820062004280200100c200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a10172202200041c8016a22012903001079101520022001290300107a200041d0016a2104200228020c200241106a28020047044010000b2002280204210820022802002107200541c0046a10172101200410830121062001200541c0026a10b201220310b3012001200620032802046a20032802006b1015200120041084010240200128020c200141106a280200460440200141046a2104200128020021060c010b200141046a2104100020012802002106200128020c2001280210460d0010000b2007200820062004280200100c200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200041a8016a200041b0016a10b501200541c0066a1017220220004190016a22012903001079101520022001290300107a200228020c200241106a28020047044010000b2002280204210420022802002108200541c0046a1017210120002d009801107421072001200541c0026a10b201220310b3012001200720032802046a20032802006b1015200120002d00980110200240200128020c200141106a280200460440200141046a2107200128020021060c010b200141046a2107100020012802002106200128020c2001280210460d0010000b2008200420062007280200100c200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a10172201200041f0006a22022903001079101520012002290300107a200041f8006a2104200128020c200141106a28020047044010000b2001280204210820012802002107200541c0046a101721022004107d21062002200541c0026a10b201220310b3012002200620032802046a20032802006b101502402002200520041018101d220228020c200241106a280200460440200241046a2104200228020021060c010b200241046a2104100020022802002106200228020c2002280210460d0010000b2007200820062004280200100c200328020022040440200320043602040b200228020c22030440200220033602100b200128020c22020440200120023602100b200541c0066a10172202200041d0006a22012903001079101520022001290300107a200228020c200241106a28020047044010000b2002280204210420022802002108200541c0046a101721012000290358107921072001200541c0026a10b201220310b3012001200720032802046a20032802006b101520012000290358107a0240200128020c200141106a280200460440200141046a2107200128020021060c010b200141046a2107100020012802002106200128020c2001280210460d0010000b2008200420062007280200100c200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a10172202200041386a22012903001079101520022001290300107a200228020c200241106a28020047044010000b2002280204210420022802002108200541c0046a101721012000280240107821072001200541c0026a10b201220310b3012001200720032802046a20032802006b10152001200028024010200240200128020c200141106a280200460440200141046a2107200128020021060c010b200141046a2107100020012802002106200128020c2001280210460d0010000b2008200420062007280200100c200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a10172202200041206a22012903001079101520022001290300107a200228020c200241106a28020047044010000b2002280204210420022802002108200541c0046a1017210120002f0128107621072001200541c0026a10b201220310b3012001200720032802046a20032802006b1015200120002f012810200240200128020c200141106a280200460440200141046a2107200128020021060c010b200141046a2107100020012802002106200128020c2001280210460d0010000b2008200420062007280200100c200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a1017220220002903081079101520022000290308107a200228020c200241106a28020047044010000b2002280204210420022802002108200541c0046a1017210120002d0010107421072001200541c0026a10b201220310b3012001200720032802046a20032802006b1015200120002d001010200240200128020c200141106a280200460440200141046a2107200128020021060c010b200141046a2107100020012802002106200128020c2001280210460d0010000b2008200420062007280200100c200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0086a24000b2601017f02402000280204450d0020002802002d000041c001490d00200010b60121010b20010b800101037f230041106b22012400200010ae0102400240200010af01450d002000280204450d0020002802002d000041c001490d010b10000b200141086a200010b001200128020c220041024f044010000b200128020821020340200004402000417f6a210020022d00002103200241016a21020c010b0b200141106a240020030b5801027f230041206b22012400200141186a4100360200200141106a4200370300200141086a42003703002001420037030020012000ad42ff01834200105b210020012802002102200041046a101b200141206a240020020b8b0101037f230041106b22012400200010ae0102400240200010af01450d002000280204450d0020002802002d000041c001490d010b10000b200141086a200010b001200128020c220041034f044010000b200128020821030340200004402000417f6a210020032d00002002410874722102200341016a21030c010b0b200141106a2400200241ffff03710b5401017f230041206b22012400200141186a4100360200200141106a4200370300200141086a4200370300200142003703002001200041ffff0371101f200128020021002001410472101b200141206a240020000b860101037f230041106b22012400200010ae0102400240200010af01450d002000280204450d0020002802002d000041c001490d010b10000b200141086a200010b001200128020c220041054f044010000b200128020821030340200004402000417f6a210020032d00002002410874722102200341016a21030c010b0b200141106a240020020b4f01017f230041206b22012400200141186a4100360200200141106a4200370300200141086a42003703002001420037030020012000101f200128020021002001410472101b200141206a240020000b5001027f230041206b22012400200141186a4100360200200141106a4200370300200141086a4200370300200142003703002001200010b401200128020021022001410472101b200141206a240020020b0a00200020014200105e0b1a0020004200370200200041086a4100360200200010b70120000ba40201057f230041206b22022400024002402000280204044020002802002d000041c001490d010b200241086a107b1a0c010b200241186a200010b001200010b80121030240024002400240200228021822000440200228021c220520034f0d010b41002100200241106a410036020020024200370308410021050c010b200241106a4100360200200242003703082000200520032003417f461b22046a21052004410a4b0d010b200220044101743a0008200241086a41017221030c010b200441106a4170712206104021032002200436020c20022006410172360208200220033602100b03402000200546450440200320002d00003a0000200341016a2103200041016a21000c010b0b200341003a00000b2001200241086a10b901200241206a24000b5801027f230041306b22012400200141286a4100360200200141206a4200370300200141186a420037030020014200370310200141106a200120001018101a210020012802102102200041046a101b200141306a240020020b0e002001200010734100473a00000b4401027f230041f00b6b2202240020001072410247044010000b200220004101106c200210ba01210020021070210320022000200111000020031071200241f00b6a24000b7b01027f230041900c6b220224002000106f200241086a10702103200241086a20011101002100200241f80b6a10172201200010bb01101520012000108c01200128020c200141106a28020047044010000b20012802002001280204100e200128020c22000440200120003602100b20031071200241900c6a24000b180020004200370200200041086a41003602002000107b1a0b2801017f230041206b22022400200241086a20004100106c200241086a2001107c200241206a24000b5001017f230041206b22012400200141186a4100360200200141106a4200370300200141086a4200370300200142003703002001200010bc01200128020021002001410472101b200141206a240020000b6e01027f230041406a2202240020004101101c2100200241386a4100360200200241306a4200370300200241286a420037030020024200370320200241206a200241106a20011018101a21032000200228022010152000200220011018101d1a200341046a101b200241406b24000be10201027f02402001450d00200041003a0000200020016a2203417f6a41003a000020014103490d00200041003a0002200041003a00012003417d6a41003a00002003417e6a41003a000020014107490d00200041003a00032003417c6a41003a000020014109490d002000410020006b41037122026a220341003602002003200120026b417c7122026a2201417c6a410036020020024109490d002003410036020820034100360204200141786a4100360200200141746a410036020020024119490d002003410036021820034100360214200341003602102003410036020c200141706a41003602002001416c6a4100360200200141686a4100360200200141646a41003602002002200341047141187222026b2101200220036a2102034020014120490d0120024200370300200241186a4200370300200241106a4200370300200241086a4200370300200241206a2102200141606a21010c000b000b20000b19002000107b1a2000410c6a107b1a200041186a107b1a20000b5701017f230041206b22022400200241086a20004100106c200241086a2001108201200241086a20004101106c200241086a2001410c6a107c200241086a20004102106c200241086a200141186a107c200241206a24000b7a01027f230041406a22012400200141186a4100360200200141106a4200370300200141086a4200370300200142003703002001410010192202200010bc012002200141306a2000410c6a1018101a200141206a200041186a1018101a41011019210020012802002102200041046a101b200141406b240020020ba40101047f230041e0006b2202240020004103101c2100200241d8006a4100360200200241d0006a4200370300200241c8006a420037030020024200370340200241406b200110bc01200241406b200241306a2001410c6a22031018101a200241206a200141186a22041018101a2105200020022802401015200020011084012000200241106a20031018101d200220041018101d1a200541046a101b200241e0006a24000b3902017f017e230041106b220124002001200010bd0120012903002102200141106a2400420020024201837d200242018885a74110744110750b6202027f017e230041206b22012400200141186a4100360200200141106a4200370300200141086a42003703002001420037030020012000ad42308622034230872003423f8710be01210020012802002102200041046a101b200141206a240020020b1301017e20002001ac22022002423f8710bf010b3302017f017e230041106b220124002001200010bd0120012903002102200141106a2400420020024201837d200242018885a70b5201027f230041206b22012400200141186a4100360200200141106a4200370300200141086a4200370300200142003703002001200010c001210020012802002102200041046a101b200141206a240020020b4202017f027e230041106b220124002001200010bd01200141086a290300210320012903002102200141106a2400420020024201837d2003423f86200242018884850b5701037f230041206b22012400200141186a4100360200200141106a4200370300200141086a420037030020014200370300200120002000423f8710be01210220012802002103200241046a101b200141206a240020030b0e00200020012001423f8710bf010bb10201047f230041d0006b22022400024002402000280204450d0020002802002d000041c001490d002000107221032001280208200128020022046b4101752003490440200120022003200128020420046b410175200141086a10c101220310c201200310c3010b200241286a200010c401200241186a200010c501200141086a21050340200228022c200228021c46044020022802302002280220460d030b2002200241286a10c6012002107521030240200128020422002001280208490440200020033b01002001200041026a3602040c010b200241386a2001200020012802006b410175220041016a10552000200510c10121002002280240220420033b01002002200441026a3602402001200010c201200010c3010b200241286a10c7010c000b000b10000b200241d0006a24000b9c0101037f230041206b22012400200141186a4100360200200141106a4200370300200141086a420037030020014200370300024020002802002000280204460440200110c8010c010b200141001019210220002802042103200028020021000340200020034604402002410110191a05200220002f0100101f200041026a21000c010b0b0b200128020021002001410472101b200141206a240020000b4301017f2000200128020420012802006b410175101c21022001280204210020012802002101034020002001470440200220012f01001020200141026a21010c010b0b0be20201057f23004190016b22022400024002402000280204450d0020002802002d000041c001490d00200241c8006a200010c401200241386a200010c501200241146a21040340200228024c200228023c46044020022802502002280240460d030b200241206a200241c8006a10c601200241086a107b21002004107b2105200241206a10c901410247044010000b20024180016a107b2103200241e8006a200241206a4100106c200241e8006a2003107c2000200310b901200241d8006a107b2103200241e8006a200241206a4101106c200241e8006a2003107c2005200310b9012001200241e8006a2000104322062802004504404128104022032002290308370210200341186a200241106a280200360200200010b701200341246a200441086a2802003602002003411c6a2004290200370200200510b701200120022802682006200310450b200241c8006a10c7010c000b000b10000b20024190016a24000bd00101047f230041e0006b22012400200141206a4100360200200141186a4200370300200141106a42003703002001420037030802402000280208450440200141086a10c8010c010b200041046a2103200141086a410010192102200141346a2104200028020021000340200020034604402002410110191a05200141286a200041106a1051200241001019200141d0006a200141286a1018101a200141406b20041018101a410110191a2000103021000c010b0b0b20012802082100200141086a410472101b200141e0006a240020000b6101027f230041206b2202240020002001280208101c2103200141046a210020012802002101034020002001460440200241206a24000520034102101c200241106a200141106a1018101d20022001411c6a1018101d1a2001103021010c010b0b0bce0101037f230041206b22022400024002402000280204044020002802002d000041c001490d010b20024100360208200242003703000c010b200241186a200010b00120022802182103200241106a200010b00120022802102104200010b80121002002410036020820024200370300200020046a20036b2200450d0020022000104b20004101480d002002200228020420032000103c20006a3602040b2001280200044020014100360208200142003702000b2001200228020036020020012002290204370204200241206a24000b5301017f230041206b22022400200241186a4100360200200241106a4200370300200241086a4200370300200242003703002002200020011014210020022802002101200041046a101b200241206a240020010b2c01037f200041f8006a21022000210103402001107b21032001410c6a21012003410c6a2002470d000b20000b6101037f230041306b22022400200010c901410a47044010000b03402003410a460440200241306a240005200241206a107b2104200241086a20002003106c200241086a2004107c2001200410b9012001410c6a2101200341016a21030c010b0b0b800101037f230041306b22012400200141186a4100360200200141106a4200370300200141086a42003703002001420037030020014100101921030340200241f800464504402003200141206a200020026a1018101a1a2002410c6a21020c010b0b200341011019210220012802002103200241046a101b200141306a240020030b4401027f230041106b220224002000410a101c2103410021000340200041f800460440200241106a24000520032002200020016a1018101d1a2000410c6a21000c010b0b0b10002000107b1a2000410036020c20000b5d01027f230041306b22022400200010c901410247044010000b200241206a107b2103200241086a20004100106c200241086a2003107c2001200310b901200241086a20004101106c2001200241086a108d0136020c200241306a24000b7301027f230041406a22012400200141286a4100360200200141206a4200370300200141186a4200370300200142003703102001200010382100200141106a41001019200141306a20001018101a200028020c10c00141011019210020012802102102200041046a101b200141406b240020020b2a01017f230041106b2202240020004102101c200220011018101d200128020c108c01200241106a24000bd70101047f230041d0006b22022400024002402000280204450d0020002802002d000041c001490d00200241406b200010c401200241306a200010c501200241106a210403402002280244200228023446044020022802482002280238460d030b200241186a200241406b10c601200241186a200241086a107b2200107c2001200241cc006a200010432205280200450440411c104022032002290308370210200341186a2004280200360200200010b7012001200228024c2005200310450b200241406b10c7010c000b000b10000b200241d0006a24000b9e0101037f230041306b22012400200141186a4100360200200141106a4200370300200141086a42003703002001420037030002402000280208450440200110c8010c010b200041046a21032001410010192102200028020021000340200020034604402002410110191a052002200141206a200041106a1018101a1a2000103021000c010b0b0b200128020021002001410472101b200141306a240020000b4f01027f230041106b2202240020002001280208101c2103200141046a210020012802002101034020002001460440200241106a24000520032002200141106a1018101d1a2001103021010c010b0b0b9f0101027f23004190046b22022400200010ae0120024188046a200010b001200228028c042103024002402000280204450d0020034180024b0d0020002802002d000041c001490d010b10000b20024188026a4180021085011a200220034180022003418002491b22006b4188046a2002280288042000103c1a200241086a20024188026a418002103c1a2001200241086a418002103c1a20024190046a24000bc00101037f230041a0086b2201240020014198026a410036020020014190026a420037030020014188026a4200370300200142003703800220012000418002103c220041a0026a2000418002103c1a200041a0046a200041a0026a418002103c1a200041a0066a200041a0046a418002103c1a41012103024003402002418002460d01200041a0066a20026a2101200241016a210220012d0000450d000b41830221030b200020033602800220004180026a410472101b200041a0086a240020030bec0101037f230041d0006b22022400024002402000280204450d0020002802002d000041c001490d00200241406b200010c401200241306a200010c501200241106a210403402002280244200228023446044020022802482002280238460d030b200241186a200241406b10c601200241186a200241086a107b2203107c411410402200410036020020002002290308370208200041106a2004280200360200200310b70120002001360204200128020021032001200036020020002003360200200320003602042001200128020841016a360208200241406b10c7010c000b000b10000b200241d0006a24000b4d01037f02402000280208450d00200028020422012802002202200028020022032802043602042000410036020820032802042002360200034020002001460d01200128020421010c000b000b0b9d0101037f230041306b22012400200141186a4100360200200141106a4200370300200141086a42003703002001420037030002402000280208450440200110c8010c010b200041046a2102200141001019210303402002280200220220004604402003410110191a052003200141206a200241086a1018101a1a200241046a21020c010b0b0b200128020021022001410472101b200141306a240020020b4e01027f230041106b22032400200141046a210220002001280208101c21000340200228020022022001460440200341106a24000520002003200241086a1018101d1a200241046a21020c010b0b0bd10102037f027e230041406a22022400200010ae01200241386a200010b001200228023c2103024002402000280204450d00200341144b0d0020002802002d000041c001490d010b10000b200241306a22004100360200200241286a220442003703002002420037032020022003411420034114491b22036b41346a20022802382003103c1a200241186a20002802002200360200200241106a20042903002205370300200220022903202206370308200141106a2000360000200141086a200537000020012006370000200241406b24000b850202037f027e23004180016b22012400200141306a4100360200200141286a4200370300200141206a4200370300200141086a200041086a2900002204370300200141106a200041106a280000220236020020014200370318200120002900002205370300200141406b2004370300200141c8006a2002360200200141d8006a2004370300200141e0006a20023602002001200537033820012005370350200141f8006a2002360200200141f0006a200437030020012005370368410121020240034020034114460d01200141e8006a20036a2100200341016a210320002d0000450d000b411521020b20012002360218200141186a410472101b20014180016a240020020b750020004200370210200042ffffffff0f370208200020023602042000200136020002402003410871450d00200010cd0120024f0d002003410471044010000c010b200042003702000b02402003411071450d00200010cd0120024d0d0020034104710440100020000f0b200042003702000b20000b4101017f200028020445044010000b0240200028020022012d0000418101470d00200028020441014d047f100020002802000520010b2c00014100480d0010000b0b990101037f200028020445044041000f0b200010ae01200028020022022c0000220141004e044020014100470f0b027f4101200141807f460d001a200141ff0171220341b7014d0440200028020441014d047f100020002802000520020b2d00014100470f0b4100200341bf014b0d001a2000280204200141ff017141ca7e6a22014d047f100020002802000520020b20016a2d00004100470b0bd60101047f200110b8012204200128020422024b04401000200128020421020b200128020021052000027f02400240200204404100210120052c00002203417f4a0d01027f200341ff0171220141bf014d04404100200341ff017141b801490d011a200141c97e6a0c010b4100200341ff017141f801490d001a200141897e6a0b41016a21010c010b4101210120050d000c010b41002103200120046a20024b0d0020022001490d00410020022004490d011a200120056a2103200220016b20042004417f461b0c010b41000b360204200020033602000bc20101057f230041406a22022400200241286a101722032000290300107a200328020c200341106a28020047044010000b02402003280200220020032802042205100a22064504400c010b2002410036022020024200370318200241186a200610582000200520022802182200200228021c220520006b100b417f47044020012002200041016a20052000417f736a106b10ba013a0000200621040b2000450d002002200036021c0b200328020c22000440200320003602100b200241406b240020040b3000200041003602082000420037020020004101104b200028020441fe013a00002000200028020441016a36020420000b6101037f200028020c200041106a28020047044010000b200028020422022001280204200128020022036b22016a220420002802084b047f20002004105c20002802040520020b20002802006a20032001103c1a2000200028020420016a3602040b0b00200020014200105b1a0b8e0201067f230041406a22042400200441286a1017220220002903001079101520022000290300107a200228020c200241106a28020047044010000b2002280204210620022802002107200441106a1017210020012d000010bb0121052000200410b201220310b3012000200520032802046a20032802006b1015200020012c0000108c010240200028020c200041106a280200460440200041046a2101200028020021050c010b200041046a2101100020002802002105200028020c2000280210460d0010000b2007200620052001280200100c200328020022010440200320013602040b200028020c22030440200020033602100b200228020c22000440200220003602100b200441406b24000b820101047f230041106b2201240002402000280204450d0020002802002d000041c001490d00200141086a200010d101200128020c210003402000450d0120014100200128020822032003200010cf0122046a20034520002004497222031b3602084100200020046b20031b2100200241016a21020c000b000b200141106a240020020b2201017f03402001410c470440200020016a4100360200200141046a21010c010b0b0b800301037f200028020445044041000f0b200010ae0141012102024020002802002c00002201417f4a0d00200141ff0171220341b7014d0440200341807f6a0f0b02400240200141ff0171220141bf014d0440024020002802042201200341c97e6a22024d047f100020002802040520010b4102490d0020002802002d00010d0010000b200241054f044010000b20002802002d000145044010000b4100210241b7012101034020012003460440200241384f0d030c0405200028020020016a41ca7e6a2d00002002410874722102200141016a21010c010b000b000b200141f7014d0440200341c07e6a0f0b024020002802042201200341897e6a22024d047f100020002802040520010b4102490d0020002802002d00010d0010000b200241054f044010000b20002802002d000145044010000b4100210241f701210103402001200346044020024138490d0305200028020020016a418a7e6a2d00002002410874722102200141016a21010c010b0b0b200241ff7d490d010b10000b20020b5c00024020002d0000410171450440200041003b01000c010b200028020841003a00002000410036020420002d0000410171450d00200041003602000b20002001290200370200200041086a200141086a280200360200200110b7010b3902017f017e230041106b220124002001200010bd0120012903002102200141106a2400420020024201837d200242018885a74118744118750b6202027f017e230041206b22012400200141186a4100360200200141106a4200370300200141086a42003703002001420037030020012000ad42388622034238872003423f8710be01210020012802002102200041046a101b200141206a240020020b2701017f230041106b22022400200041001019200220011018101a410110191a200241106a24000ba10102027f027e230041106b22022400200110ae0102400240200110af01450d002001280204450d0020012802002d000041c001490d010b10000b200241086a200110b001200228020c220141114f044010000b20022802082103034020010440200542088620044238888421052001417f6a210120033100002004420886842104200341016a21030c010b0b2000200437030020002005370308200241106a24000b2301017e20002002423f87220320014201868520024201862001423f8884200385105b0b2301017e20002002423f87220320014201868520024201862001423f8884200385105e0b1301017e20002001ac22022002423f8710be010b4c01017f2000410036020c200041106a2003360200200104402001105321040b200020043602002000200420024101746a22023602082000200420014101746a36020c2000200236020420000b870101037f200120012802042000280204200028020022046b22036b2202360204200341004a0440200220042003103c1a200128020421020b200028020021032000200236020020012003360204200028020421022000200128020836020420012002360208200028020821022000200128020c3602082001200236020c200120012802043602000b2b01027f200028020821012000280204210203402001200247044020002001417e6a22013602080c010b0b0b0b0020002001410110ca010b0b0020002001410010ca010b170020002001280204200141086a280200411c10ad011a0bb70102057f017e230041106b22032400200041046a210102402000280200220204402001280200220504402005200041086a2802006a21040b20002004360204200041086a2002360200200341086a200141002004200210cf0110d00120002003290308220637020420004100200028020022012006422088a76b2202200220014b1b3602000c010b200020012802002201047f2001200041086a2802006a0541000b360204200041086a41003602000b200341106a24000b3901017f027f200041186a28020022010440200041086a280200200041146a2802002001105a0c010b20000b2201200128020041016a3602000b220002402000280204044020002802002d000041bf014b0d010b10000b200010b6010be70101037f230041106b2204240020004200370200200041086a410036020020012802042103024002402002450440200321020c010b410021022003450d002003210220012802002d000041c001490d00200441086a200110d10120004100200428020c220120042802082202200110cf0122032003417f461b20024520012003497222031b220536020820004100200220031b3602042000200120056b3602000c010b20012802002103200128020421012000410036020020004100200220016b20034520022001497222021b36020820004100200120036a20021b3602040b200441106a24000b3501017f230041106b220041908c0436020c41800c200028020c41076a417871220036020041840c200036020041880c3f003602000b100020020440200020012002103c1a0b0b3001017f200028020445044041000f0b4101210120002802002c0000417f4c047f200010ce01200010b8016a0520010b0b5b00027f027f41002000280204450d001a410020002802002c0000417f4a0d011a20002802002d0000220041bf014d04404100200041b801490d011a200041c97e6a0c010b4100200041f801490d001a200041897e6a0b41016a0b0b2901017f230041206b22022400200241086a20002001411410ad0110cd012100200241206a240020000b5b01027f2000027f0240200128020022054504400c010b200220036a200128020422014b0d0020012002490d00410020012003490d011a200220056a2104200120026b20032003417f461b0c010b41000b360204200020043602000b2401017f200110b801220220012802044b044010000b20002001200110ce01200210d0010b7b01037f0340024020002802102201200028020c460d00200141786a2802004504401000200028021021010b200141786a22022002280200417f6a220336020020030d002000200236021020002001417c6a2802002201200028020420016b220210026a10d301200120002802006a22012002200110030c010b0b0b3601017f200028020820014904402001106720002802002000280204103c210220002001360208200020023602000b200020013602040b0bfa0301004180080bf203746f70696331006461746131006a735f636f6e7472616374006576656e740073657455696e7433324576740073657455696e743136457674007472616e7366657200696e69740073657455696e74380067657455696e74380073657455696e7431360067657455696e7431360073657455696e7433320067657455696e7433320073657455696e7436340067657455696e74363400736574537472696e6700676574537472696e6700736574426f6f6c00676574426f6f6c00736574436861720067657443686172007365744d657373616765006765744d657373616765007365744d794d657373616765006765744d794d65737361676500736574496e743800676574496e743800736574496e74313600676574496e74313600736574496e74333200676574496e74333200736574496e74363400676574496e74363400736574566563746f7200676574566563746f72007365744d6170006765744d617000746573744d756c7469506172616d730073657442797465730067657442797465730073657441727261790067657441727261790073657450616972006765745061697200736574536574006765745365740073657446697865644861736800676574466978656448617368007365744c697374006765744c69737400736574416464726573730067657441646472657373' +cabi = [{"constant":false,"input":[{"name":"input","type":"string[10]"}],"name":"setArray","output":"void","type":"Action"},{"constant":false,"input":[{"name":"input","type":"FixedHash<256>"}],"name":"setFixedHash","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getFixedHash","output":"FixedHash<256>","type":"Action"},{"constant":true,"input":[],"name":"getChar","output":"int8","type":"Action"},{"baseclass":[],"fields":[{"name":"head","type":"string"}],"name":"message","type":"struct"},{"constant":false,"input":[{"name":"msg","type":"message"}],"name":"setMessage","output":"void","type":"Action"},{"constant":false,"input":[{"name":"input","type":"int32"}],"name":"setInt32","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getPair","output":"pair","type":"Action"},{"anonymous":false,"input":[{"name":"topic","type":"string"},{"name":"arg1","type":"string"}],"name":"transfer","topic":1,"type":"Event"},{"anonymous":false,"input":[{"name":"topic","type":"string"},{"name":"arg1","type":"string"},{"name":"arg2","type":"uint16"}],"name":"setUint16Evt","topic":1,"type":"Event"},{"constant":false,"input":[{"name":"addr","type":"FixedHash<20>"}],"name":"setAddress","output":"void","type":"Action"},{"anonymous":false,"input":[{"name":"topic1","type":"string"},{"name":"topic2","type":"uint32"},{"name":"arg1","type":"string"},{"name":"arg2","type":"uint32"},{"name":"arg3","type":"uint32"}],"name":"setUint32Evt","topic":2,"type":"Event"},{"constant":false,"input":[],"name":"init","output":"void","type":"Action"},{"constant":false,"input":[{"name":"input","type":"uint8"}],"name":"setUint8","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getUint8","output":"uint8","type":"Action"},{"constant":false,"input":[{"name":"input","type":"uint16"}],"name":"setUint16","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getUint16","output":"uint16","type":"Action"},{"constant":false,"input":[{"name":"input","type":"uint32"}],"name":"setUint32","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getUint32","output":"uint32","type":"Action"},{"constant":false,"input":[{"name":"input","type":"uint64"}],"name":"setUint64","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getUint64","output":"uint64","type":"Action"},{"constant":false,"input":[{"name":"input","type":"string"}],"name":"setString","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getString","output":"string","type":"Action"},{"constant":false,"input":[{"name":"input","type":"bool"}],"name":"setBool","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getBool","output":"bool","type":"Action"},{"constant":false,"input":[{"name":"input","type":"int8"}],"name":"setChar","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getMessage","output":"message","type":"Action"},{"baseclass":["message"],"fields":[{"name":"body","type":"string"},{"name":"end","type":"string"}],"name":"my_message","type":"struct"},{"constant":false,"input":[{"name":"msg","type":"my_message"}],"name":"setMyMessage","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getMyMessage","output":"my_message","type":"Action"},{"constant":false,"input":[{"name":"input","type":"int8"}],"name":"setInt8","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getInt8","output":"int8","type":"Action"},{"constant":false,"input":[{"name":"input","type":"int16"}],"name":"setInt16","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getInt16","output":"int16","type":"Action"},{"constant":true,"input":[],"name":"getInt32","output":"int32","type":"Action"},{"constant":false,"input":[{"name":"input","type":"int64"}],"name":"setInt64","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getInt64","output":"int64","type":"Action"},{"constant":false,"input":[{"name":"vec","type":"uint16[]"}],"name":"setVector","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getVector","output":"uint16[]","type":"Action"},{"constant":false,"input":[{"name":"input","type":"map"}],"name":"setMap","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getMap","output":"map","type":"Action"},{"constant":false,"input":[{"name":"msg","type":"message"},{"name":"input1","type":"int32"},{"name":"input2","type":"bool"}],"name":"testMultiParams","output":"void","type":"Action"},{"constant":false,"input":[{"name":"input","type":"uint8[]"}],"name":"setBytes","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getBytes","output":"uint8[]","type":"Action"},{"constant":true,"input":[],"name":"getArray","output":"string[10]","type":"Action"},{"constant":false,"input":[{"name":"input","type":"pair"}],"name":"setPair","output":"void","type":"Action"},{"constant":false,"input":[{"name":"input","type":"set"}],"name":"setSet","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getSet","output":"set","type":"Action"},{"constant":false,"input":[{"name":"input","type":"list"}],"name":"setList","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getList","output":"list","type":"Action"},{"constant":true,"input":[],"name":"getAddress","output":"FixedHash<20>","type":"Action"}] + +# Instantiate and deploy contract +Payable = platon.wasmcontract(abi=cabi, bytecode=bytecode,vmtype=1) + +tx_hash = Payable.constructor().transact( + { + 'from':from_address, + 'gas':1500000, + } +) + +# Wait for the transaction to be mined, and get the transaction receipt +tx_receipt = platon.waitForTransactionReceipt(tx_hash) +print(tx_receipt) + + +# Create the contract instance with the newly-deployed address +payable = platon.wasmcontract(address=tx_receipt.contractAddress, abi=cabi,vmtype=1) + +tx_hash0 = payable.functions.setBool(false).transact( + { + 'from':from_address, + 'gas':1500000, + } +) +print(platon.waitForTransactionReceipt(tx_hash0)) +print('get : {}'.format( + payable.functions.getBool().call() +)) +# get : True +# get : False + + +tx_hash1 = payable.functions.setInt64(-9223372036854775808).transact( + { + 'from':from_address, + 'gas':1500000, + } +) +print(platon.waitForTransactionReceipt(tx_hash1)) +print('get : {}'.format( + payable.functions.getInt64().call() +)) +# get : -9223372036854775808 + + +tx_hash2 = payable.functions.setUint64(18446744073709551615).transact( + { + 'from':from_address, + 'gas':1500000, + } +) +print(platon.waitForTransactionReceipt(tx_hash2)) +print('get : {}'.format( + payable.functions.getUint64().call() +)) +# get : 18446744073709551615 + + +tx_hash3 = payable.functions.setInt32(-2147483648).transact( + { + 'from':from_address, + 'gas':1500000, + } +) +print(platon.waitForTransactionReceipt(tx_hash3)) +print('get : {}'.format( + payable.functions.getInt32().call() +)) +# get : -2147483648 + + +tx_hash4 = payable.functions.setUint32(4294967295).transact( + { + 'from':from_address, + 'gas':1500000, + } +) +print(platon.waitForTransactionReceipt(tx_hash4)) +print('get : {}'.format( + payable.functions.getUint32().call() +)) +# get : 4294967295 + +tx_hash5 = payable.functions.setString('helloworld').transact( + { + 'from':from_address, + 'gas':1500000, + } +) +print(platon.waitForTransactionReceipt(tx_hash5)) +print('get : {}'.format( + payable.functions.getString().call() +)) +# get : helloworld + + +tx_hash6 = payable.functions.setChar(62).transact( + { + 'from':from_address, + 'gas':1500000, + } +) +print(platon.waitForTransactionReceipt(tx_hash6)) +print('get : {}'.format( + payable.functions.getChar().call() +)) +# get : 62 + +tx_hash7 = payable.functions.setAddress('lax1du4w3q0h5gpxh2vpdvtl7m8h2p9qj40a2krhx7').transact( + { + 'from':from_address, + 'gas':1500000, + } +) +print(platon.waitForTransactionReceipt(tx_hash7)) +print('get : {}'.format( + payable.functions.getAddress().call() +)) +# get : lax1du4w3q0h5gpxh2vpdvtl7m8h2p9qj40a2krhx7 + + +liststring=['hello','this way','go home'] +tx_hash8 = payable.functions.setList(liststring).transact( + { + 'from':from_address, + 'gas':1500000, + } +) +print(platon.waitForTransactionReceipt(tx_hash8)) +print('get : {}'.format( + payable.functions.getList().call() +)) +# get : ['hello', 'this way', 'go home'] + + +setstring={'hello','this way','go home'} +tx_hash8a = payable.functions.setSet(setstring).transact( + { + 'from':from_address, + 'gas':1500000, + } +) +print(platon.waitForTransactionReceipt(tx_hash8a)) +print('get : {}'.format( + payable.functions.getSet().call() +)) +# get : {'hello', 'go home', 'this way'} + + + +uintbyte=['0x23','0xd1','0xf3'] +tx_hash9 = payable.functions.setBytes(uintbyte).transact( + { + 'from':from_address, + 'gas':1500000, + } +) +print(platon.waitForTransactionReceipt(tx_hash9)) +print('get : {}'.format( + payable.functions.getBytes().call() +)) +# get : ['0x23', '0xd1', '0xf3'] + +uint16vec=[32,97,10022] +tx_hash9a = payable.functions.setVector(uint16vec).transact( + { + 'from':from_address, + 'gas':1500000, + } +) +print(platon.waitForTransactionReceipt(tx_hash9a)) +print('get : {}'.format( + payable.functions.getVector().call() +)) +# get : [32, 97, 10022] + + + +mapstr=[['hello world','may the force with you'],['how are you','fine,thanks and you ?']] +tx_hash10 = payable.functions.setMap(mapstr).transact( + { + 'from':from_address, + 'gas':1500000, + } +) +print(platon.waitForTransactionReceipt(tx_hash10)) +print('get : {}'.format( + payable.functions.getMap().call() +)) +# get : [['hello world', 'may the force with you'], ['how are you', 'fine,thanks and you ?']] + + +arraystr=['hello','world','may', 'the', 'force', 'with', 'you','impossible','dancing', 'in dark'] +tx_hash11 = payable.functions.setArray(arraystr).transact( + { + 'from':from_address, + 'gas':1500000, + } +) +print(platon.waitForTransactionReceipt(tx_hash11)) +print('get : {}'.format( + payable.functions.getArray().call() +)) +# get : ['hello', 'world', 'may', 'the', 'force', 'with', 'you', 'impossible', 'dancing', 'in dark'] + + +pairlist=['hello',-123] +tx_hash12 = payable.functions.setPair(pairlist).transact( + { + 'from':from_address, + 'gas':1500000, + } +) +print(platon.waitForTransactionReceipt(tx_hash12)) +print('get : {}'.format( + payable.functions.getPair().call() +)) +# get : ['hello', -123] + + +mymessage=[['HelloWorld'], 'Wasm', 'Good'] +tx_hash13 = payable.functions.setMyMessage(mymessage).transact( + { + 'from':from_address, + 'gas':1500000, + } +) +print(platon.waitForTransactionReceipt(tx_hash13)) +print('get : {}'.format( + payable.functions.getMyMessage().call() +)) +# get : [['HelloWorld'], 'Wasm', 'Good'] + +message=['HelloWorld'] +tx_hash14 = payable.functions.setMessage(message).transact( + { + 'from':from_address, + 'gas':1500000, + } +) +print(platon.waitForTransactionReceipt(tx_hash14)) +print('get : {}'.format( + payable.functions.getMessage().call() +)) +# get : ['HelloWorld'] + + + +# from hexbytes import ( +# HexBytes, +# ) +# fixhash=HexBytes('0x271abcb306a89cef79e32f687523dbac47ee5710bc37a284bd9598e32810b394') +# tx_hash15 = payable.functions.setFixedHash(fixhash).transact( +# { +# 'from':from_address, +# 'gas':1500000, +# } +# ) +# print(platon.waitForTransactionReceipt(tx_hash15)) +# print('get : {}'.format( +# payable.functions.getFixedHash().call() +# )) + diff --git a/tests/sdk_test1.py b/tests/sdk_test1.py new file mode 100644 index 0000000..f55dba0 --- /dev/null +++ b/tests/sdk_test1.py @@ -0,0 +1,81 @@ +from client_sdk_python import Web3, HTTPProvider +from client_sdk_python.eth import PlatON +from client_sdk_python.packages.platon_keys.utils import bech32,address +from hexbytes import HexBytes +from client_sdk_python.packages.eth_utils import to_checksum_address +true = True +false = False +# get blockNumber +# w3 = Web3(HTTPProvider("http://10.1.1.2:6789")) +# platon = PlatON(w3) +w3 = Web3(HTTPProvider("http://10.1.1.5:6789")) +platon = PlatON(w3) +print(w3.isConnected()) +from_address = "lax1yjjzvjph3tw4h2quw6mse25y492xy7fzwdtqja" +send_privatekey = "b7a7372e78160f71a1a75e03c4aa72705806a05cf14ef39c87fdee93d108588c" +block_number = platon.blockNumber +print(block_number) +print(platon.protocolVersion) +print(platon.accounts) +print(platon.syncing) +print(platon.gasPrice) +print(platon.evidences) +print(platon.consensusStatus) + +# get Balance +from_address = 'lax1yjjzvjph3tw4h2quw6mse25y492xy7fzwdtqja' +# address = '0x493301712671Ada506ba6Ca7891F436D29185821' +balance = platon.getBalance(from_address) +print(balance) +platon.getPrepareQC() +platon.getStorageAt() +platon.getCode() +platon.getBlock() +platon.getBlockTransactionCount() +platon.getTransaction() +platon.getRawTransaction() +platon.getTransactionFromBlock() +platon.getTransactionByBlock() +platon.waitForTransactionReceipt() +platon.getTransactionReceipt() +platon.getTransactionCount() +platon.replaceTransaction() +platon.modifyTransaction() +platon.sendTransaction() +platon.sendRawTransaction() +platon.sign() +platon.call() +platon.estimateGas() +platon.filter() +platon.getFilterChanges() +platon.getFilterLogs() +platon.getLogs() +platon.uninstallFilter() +platon.generateGasPrice() +platon.setGasPriceStrategy() +platon.analyzeReceiptByHash() +platon.analyzeReceipt() +platon.ecrecover() + +# sendtransaction +to_address = 'lax1qqqjkfwu854vf3ze2dpy5gctmxy3gdgzsngj66' +## Address = bech32.bech32_decode(from_address) +# hrpgot, data = bech32.decode("lax", from_address) +# from_address = to_checksum_address(bytes(data)).lower() +# # arguments = tuple(address.split(",")) +# hrpgot, data = bech32.decode("lax", to_address) +# to_address = to_checksum_address(bytes(data)).lower() + +w3.personal.unlockAccount(from_address, "123456", 999999) +data={ + "from": from_address, + "to": to_address, + "value": 1, + "gas": 1000000, + "gasPrice": 1000000000, +} +# provider = RPC connection http://10.1.1.2:6789 +transaction_hex = HexBytes(platon.sendTransaction(data)).hex() +# b'{"jsonrpc":"2.0","id":2,"error":{"code":-32602,"message":"invalid argument 0: json: cannot unmarshal decoding bech32 failed: failed converting data to bytes: invalid character not part of charset: 98 into Go struct field CallArgs.from of type common.Address"}}\n' +result = platon.waitForTransactionReceipt(transaction_hex) +print(result) \ No newline at end of file diff --git a/tests/smtest1.py b/tests/smtest1.py new file mode 100644 index 0000000..832cbc1 --- /dev/null +++ b/tests/smtest1.py @@ -0,0 +1,106 @@ +from client_sdk_python import Web3, HTTPProvider +from client_sdk_python.eth import PlatON +from client_sdk_python.packages.platon_keys.utils.address import DEFAULTHRP +from client_sdk_python.packages.platon_account import Account +# from client_sdk_python.packages.gmssl import sm2,sm3,func +from hexbytes import HexBytes +# import binascii +# f = open('D:/juzhen/JS_wasmtest1.wasm','rb') +# contents=f.read() +# bytecode=binascii.b2a_hex(contents) +# import os +# dll_name = "platon_sm.dll" +# dllabspath = os.path.dirname(os.path.abspath(__file__)) + os.path.sep + dll_name +# so_name='platon_sm.so' +# soabspath=os.path.dirname(os.path.abspath(__file__)) + os.path.sep + so_name + +# import platform +# from ctypes import * +# import os + +# # bytes和int的相互转换 +# +# b = b'\x12\x34' +# n = int.from_bytes(b, byteorder='big', signed=False) +# # b'\x12\x34'->4660 +# +# n = 4660 +# b = n.to_bytes(length=2, byteorder='big', signed=False) +# # 4660->b'\x12\x34' +# +# OSname=platform.system() +# if OSname=='Windows': +# SMC = windll.LoadLibrary('./platon_sm.dll') +# elif OSname=='Linux': +# SMC = CDLL('./platon_sm.so') +# else: +# raise TypeError('Operating system not supported by SM: %s'% OSname) +# r1=int.from_bytes(os.urandom(32), byteorder='big',signed=False) +# r2=int.from_bytes(os.urandom(64), byteorder='big',signed=False) +# r1=32 +# r2=64 +# priv=c_ubyte * r1 +# publ=c_ubyte * r2 +# class keystrc(Structure): +# _fields_ = [ +# ("private",priv), +# ("public",publ)] +# keys=SMC.sm2_genKey +# keys.argtypes=[POINTER(keystrc)] +# # keys.argtypes=[c_ubyte * r1,c_ubyte * r2] +# keys.restypes=c_int +# keystruct=keystrc() +# # res=keys(byref(keystruct)) +# # key1=SMC.sm2_genKey(priv,publ) +# # key2=SMC.generate() +true = True +false = False + +# account = Account().create(net_type='lax') #,mode='SM' +# w3 = Web3(HTTPProvider("http://10.1.1.51:6789")) +w3=Web3(HTTPProvider("http://10.1.1.49:6789")) #含有国密链的节点 +platon = PlatON(w3) +print(w3.isConnected()) +# from_address = "lax1v58tvxrek2a59ffqeqzru0v76axspkad8jc5xs" +# send_privatekey = "dd127f840b8452432417140a86f4e1ce02a6c5386e20a4dd9dcdf9c7b9eed4e0" +from_address='lax1jkak6wudnp3289dav8wcvpkkdu28fqf3q7rrvc'#account.address 'SM' +send_privatekey='6d86da8039e20aca51e7f9ef84eb2d4d7e921907ff3833e7ee3a59940c2e2833' #account.privateKey.hex() 'SM' +publickey='2964a43da2380d47481457419304cf6071970cd526f52aee620c216a1e6e42f795e63f01dba99d7a8e8371dc4c3ebcf003aaa4d27ae0b5e87f112fc289f3a407' +##test +# privattekey1='55e4f51420bc4d29a420038b88174ebded209e76b72ad4fde89298c89978153d' +# publickey1='05f16e43de8465014247b1e430c295b011935b4a39be0cd6511c61ff6fdd0721a44dc43b4cc51c573344b38504e9b198c7084482cc080091fce1544ce55dc2ad' +# address1='lax1vly7jpe74ppq3n27cxf28f0hehw3lvxweh5utv' +bytecode='0061736d0100000001681260027f7f0060017f017f60027f7f017f60017f0060037f7f7f0060037f7f7f017f60000060047f7f7f7f0060047f7f7f7f017f60027f7e0060017f017e60037f7e7e0060037f7e7e017f60017e017f60057f7f7f7f7f0060037e7e7f006000017f60027e7e017f02ce020f03656e760c706c61746f6e5f70616e6963000603656e760b706c61746f6e5f73686133000703656e760d726c705f6c6973745f73697a65000103656e760f706c61746f6e5f726c705f6c697374000403656e760e726c705f62797465735f73697a65000203656e7610706c61746f6e5f726c705f6279746573000403656e760d726c705f753132385f73697a65001103656e760f706c61746f6e5f726c705f75313238000f03656e7617706c61746f6e5f6765745f696e7075745f6c656e677468001003656e7610706c61746f6e5f6765745f696e707574000303656e7617706c61746f6e5f6765745f73746174655f6c656e677468000203656e7610706c61746f6e5f6765745f7374617465000803656e7610706c61746f6e5f7365745f7374617465000703656e760c706c61746f6e5f6576656e74000703656e760d706c61746f6e5f72657475726e000003c701c5010600020200050000010202020302020400000e0000000200010002000100020000010207000200020002000002050000020101020504070003030105000405020404000001050204030001050c00050b01000005080305000106060605040a0a030103010101010101010d0901000100000003000100020100010001010001010a0d0900010000010000020100010001000100000100000100030100000108030100020100090001030100010100000c0b02080003000000030301040604010102070003000405017001050505030100020608017f0141908c040b073904066d656d6f72790200115f5f7761736d5f63616c6c5f63746f7273000f0f5f5f66756e63735f6f6e5f65786974006a06696e766f6b650068090a010041010b0426272a2b0a97b602c501050010cb010baa0301097f230041c0016b22022400200241b90810112104200241e8006a410210122103200241d8006a20041013200241c8006a20001013200241406b4100360200200241386a4200370300200241306a420037030020024200370328200241286a20022802582204200228025c101420022802482205200228024c101421062003200228022810152003200241d8006a10162003200241c8006a1016200328020c200341106a28020047044010000b2003280204210720032802002108200241106a1017210020024180016a200110182101200241a8016a4100360200200241a0016a420037030020024198016a4200370300200242003703900120024190016a41001019200241b0016a20011018101a410110192109200228029001210a200941046a101b2000200a101520004101101c20024190016a20011018101d220028020c200041106a28020047044010000b2008200720002802002000280204100d200028020c22010440200020013602100b200641046a101b200504402002200536024c0b200404402002200436025c0b200328020c22000440200320003602100b200241c0016a24000b910101027f20004200370200200041086a410036020020012102024003402002410371044020022d0000450d02200241016a21020c010b0b2002417c6a21020340200241046a22022802002203417f73200341fffdfb776a7141808182847871450d000b0340200341ff0171450d01200241016a2d00002103200241016a21020c000b000b20002001200220016b105620000b1d0020001057200041146a41003602002000420037020c20002001101c0ba40201047f230041206b2202240020024100360218200242003703100240027f4100200128020420012d00002204410176200441017122051b2204450d001a2001280208200141016a20051b2103200241106a2004104b0340200404402002280214220120032d00003a00002002200141016a3602142004417f6a2104200341016a21030c010b0b2002280210210320022802140b220420036b41204d044020002004360204200020033602002000200228021836020820024100360218200242003703100c010b20024100360208200242003703002002412010582003200228021420036b200228020022042002280204220120046b10012000200136020420002004360200200020022802083602082003450d00200220033602140b200241206a24000b8b0101017f024020012002460440410121030c010b4101210302400240200220016b2202410146044020012c0000417f4c0d010c030b200241374b0d010b200241016a21030c010b2002105920026a41016a21030b027f200041186a28020022010440200041086a280200200041146a2802002001105a0c010b20000b2201200128020020036a36020020000b13002000280208200149044020002001105c0b0b1600200020012802002200200128020420006b105d1a0b190020001057200041146a41003602002000420037020c20000b4d01017f20004200370200200041086a2202410036020020012d0000410171450440200020012902003702002002200141086a28020036020020000f0b200020012802082001280204105620000bc30c02077f027e230041306b22042400200041046a2107027f20014101460440200041086a280200200041146a280200200041186a22022802002203105a280200210120022003417f6a3602002007105f4180104f044020072000410c6a280200417c6a10600b200141384f047f2001105920016a0520010b41016a2102200041186a28020022010440200041086a280200200041146a2802002001105a0c020b20000c010b02402007105f0d00200041146a28020022014180084f0440200020014180786a360214200041086a2201280200220228020021032001200241046a360200200420033602182007200441186a10610c010b2000410c6a2802002202200041086a2802006b4102752203200041106a2205280200220620002802046b220141027549044041802010402105200220064704400240200028020c220120002802102202470d0020002802082203200028020422064b04402000200320012003200320066b41027541016a417e6d41027422026a1062220136020c2000200028020820026a3602080c010b200441186a200220066b2201410175410120011b22012001410276200041106a10632102200028020c210320002802082101034020012003470440200228020820012802003602002002200228020841046a360208200141046a21010c010b0b200029020421092000200229020037020420022009370200200029020c21092000200229020837020c2002200937020820021064200028020c21010b200120053602002000200028020c41046a36020c0c020b02402000280208220120002802042202470d00200028020c2203200028021022064904402000200120032003200620036b41027541016a41026d41027422026a106522013602082000200028020c20026a36020c0c010b200441186a200620026b2201410175410120011b2201200141036a410276200041106a10632102200028020c210320002802082101034020012003470440200228020820012802003602002002200228020841046a360208200141046a21010c010b0b200029020421092000200229020037020420022009370200200029020c21092000200229020837020c2002200937020820021064200028020821010b2001417c6a2005360200200020002802082201417c6a22023602082002280200210220002001360208200420023602182007200441186a10610c010b20042001410175410120011b200320051063210241802010402106024020022802082201200228020c2203470d0020022802042205200228020022084b04402002200520012005200520086b41027541016a417e6d41027422036a106222013602082002200228020420036a3602040c010b200441186a200320086b2201410175410120011b22012001410276200241106a280200106321032002280208210520022802042101034020012005470440200328020820012802003602002003200328020841046a360208200141046a21010c010b0b20022902002109200220032902003702002003200937020020022902082109200220032902083702082003200937020820031064200228020821010b200120063602002002200228020841046a360208200028020c2105034020002802082005460440200028020421012000200228020036020420022001360200200228020421012002200536020420002001360208200029020c21092000200229020837020c2002200937020820021064052005417c6a210502402002280204220120022802002203470d0020022802082206200228020c22084904402002200120062006200820066b41027541016a41026d41027422036a106522013602042002200228020820036a3602080c010b200441186a200820036b2201410175410120011b2201200141036a4102762002280210106321062002280208210320022802042101034020012003470440200428022020012802003602002004200428022041046a360220200141046a21010c010b0b20022902002109200220042903183702002002290208210a20022004290320370208200420093703182004200a37032020061064200228020421010b2001417c6a200528020036020020022002280204417c6a3602040c010b0b0b200441186a20071066200428021c410036020041012102200041186a0b2201200128020020026a360200200441306a240020000ba10101037f41012103024002400240200128020420012d00002202410176200241017122041b220241014d0440200241016b0d032001280208200141016a20041b2c0000417f4c0d010c030b200241374b0d010b200241016a21030c010b2002105920026a41016a21030b027f200041186a28020022010440200041086a280200200041146a2802002001105a0c010b20000b2201200128020020036a36020020000bea0101047f230041106b22042400200028020422012000280210220241087641fcffff07716a2103027f410020012000280208460d001a2003280200200241ff07714102746a0b2101200441086a20001066200428020c210203400240200120024604402000410036021420002802082103200028020421010340200320016b41027522024103490d022000200141046a22013602040c000b000b200141046a220120032802006b418020470d0120032802042101200341046a21030c010b0b2002417f6a220241014d04402000418004418008200241016b1b3602100b200020011060200441106a24000b9f0201057f2001044020002802042105200041106a2802002202200041146a280200220349044020022001ad2005ad422086843702002000200028021041086a36021020000f0b027f41002002200028020c22046b410375220641016a2202200320046b2203410275220420042002491b41ffffffff01200341037541ffffffff00491b2204450d001a200441037410400b2102200220064103746a22032001ad2005ad4220868437020020032000280210200028020c22066b22016b2105200220044103746a2102200341086a2103200141014e0440200520062001103c1a0b20002002360214200020033602102000200536020c20000f0b200041001002200028020422016a10d30141004100200120002802006a1003200010d20120000b2c01017f20002001280208200141016a20012d0000220041017122021b2001280204200041017620021b105d0bc80301087f230041c0016b22032400200341ac0810112105200341e8006a410210122104200341d8006a20051013200341c8006a20001013200341406b4100360200200341386a4200370300200341306a420037030020034200370328200341286a20032802582205200328025c101420032802482206200328024c101421072004200328022810152004200341d8006a10162004200341c8006a1016200428020c200441106a28020047044010000b2004280204210820042802002109200341106a1017210020034180016a200110182101200320023b018c01200341a8016a4100360200200341a0016a420037030020034198016a4200370300200342003703900120034190016a41001019200341b0016a20011018101a220220032f018c01101f2002410110192102200328029001210a200241046a101b2000200a101520004102101c20034190016a20011018101d220020032f018c011020200028020c200041106a28020047044010000b2009200820002802002000280204100d200028020c22010440200020013602100b200741046a101b200604402003200636024c0b200504402003200536025c0b200428020c22000440200420003602100b200341c0016a24000b0c0020002001ad4200105b1a0b0b0020002001ad4200105e0bf20301067f230041d0016b22052400200541086a419f0810112107200541f0006a410310122106200541e0006a20071013200541d0006a20001013200541c8006a4100360200200541406b4200370300200541386a420037030020054200370330200541306a2005280260220020052802641014200528025022072005280254101422082001101f2006200528023010152006200541e0006a10162006200541d0006a1016200620011020200628020c200641106a28020047044010000b200628020421092006280200210a200541186a1017210120054188016a20021018210220052004360298012005200336029401200541b8016a4100360200200541b0016a4200370300200541a8016a4200370300200542003703a001200541a0016a41001019200541c0016a20021018101a2203200528029401101f2003200528029801101f200341011019210320052802a0012104200341046a101b20012004101520014103101c200541a0016a20021018101d2201200528029401102020012005280298011020200128020c200141106a28020047044010000b200a200920012802002001280204100d200128020c22020440200120023602100b200841046a101b20070440200520073602540b20000440200520003602640b200628020c22010440200620013602100b200541d0016a24000b2e01017f230041206b22022400200241106a418d081011200241990810111010200020013a0010200241206a24000b3301017f230041206b22022400200241106a4180081011200241870810112001101e200041286a20013b0100200241206a24000b3701017f230041206b22022400200241106a4180081011200120024187081011200120011021200041406b2001360200200241206a24000b930201047f20002001470440200128020420012d00002202410176200241017122041b2102200141016a210320012802082105410a21012005200320041b210420002d0000410171220304402000280200417e71417f6a21010b200220014d0440027f2003044020002802080c010b200041016a0b210120020440200120042002104f0b200120026a41003a000020002d000041017104402000200236020420000f0b200020024101743a000020000f0b416f2103200141e6ffffff074d0440410b20014101742201200220022001491b220141106a4170712001410b491b21030b2003104022012004200210cc01200020023602042000200341017236020020002001360208200120026a41003a00000b20000b0d00200041b0016a20013a00000b0b00200041b0016a2c00000b23002000200110251a2000410c6a2001410c6a10251a200041186a200141186a10251a0b25002000200110181a2000410c6a2001410c6a10181a200041186a200141186a10181a20000b0d00200041c8026a20013a00000b0b00200041c8026a2c00000b9e0101047f2000200147044020012802042203200128020022026b41017522042000280208200028020022016b4101754d0440200041046a21052004200028020420016b41017522004b04402002200220004101746a2200200110541a200020032005104c0f0b200520022003200110543602000f0b2001044020004100360208200042003702000b2000200020041055105220022003200041046a104c0b0b3e01017f2000420037020020004100360208200128020420012802006b2202044020002002410175105220012802002001280204200041046a104c0b20000b3001027f200141046a21032001280200210203402002200346044020004188046a2001102f052002103021020c010b0b0be00201067f230041206b22042400024020002001460d00200141046a21062001280200210102402000280208450d00200028020021032000200041046a3602002000410036020820002802042102200041003602042002410036020820032802042202200320021b2102034020022203450d0120012006470440200341106a200141106a102521072003411c6a2001411c6a10251a024020032802082202450440410021020c010b2003200228020022054604402002410036020020022802042205450d012005104921020c010b200241003602042005450d002005104921020b2000200441106a2007104a2107200020042802102007200310452001103021010c010b0b0340200328020822030d000b200621010b034020012006460d01200441106a2000200141106a105020002004410c6a2004280210220341106a104a21022000200428020c2002200310452001103021010c000b000b200441206a24000b3601017f024020002802042201044003402001220028020022010d000c020b000b0340200020002802082200280200470d000b0b20000bd60101067f230041106b22022400200042003702042000200041046a2203360200200141046a21062001280200210103402001200646450440200141106a21050240027f027f0240024020032000280200460440200321040c010b20031041220441106a20051042450d010b20032802004504402002200336020c2003210420030c030b2002200436020c200441046a0c010b20002002410c6a200510430b22042802000d01200228020c0b21072002200020051050200020072004200228020010450b2001103021010c010b0b200241106a240020000b2300200041d0016a200110251a20004198016a20033a0000200041f8026a20023602000b920101047f2000200147044020012802042203200128020022026b22042000280208200028020022016b4d0440200041046a21052004200028020420016b22004b04402002200020026a22002001104d1a200020032005104c0f0b2005200220032001104d3602000f0b2001044020004100360208200042003702000b200020002004104e104b20022003200041046a104c0b0b3b01017f2000420037020020004100360208200128020420012802006b2202044020002002104b20012802002001280204200041046a104c0b20000b2601017f0340200241f800470440200020026a200120026a10251a2002410c6a21020c010b0b0b2301017f0340200020026a200120026a10181a2002410c6a220241f800470d000b20000b13002000200110251a2000200128020c36020c0b15002000200110181a2000200128020c36020c20000b3001027f200141046a210320012802002102034020022003460440200041f8066a2001103a052002103021020c010b0b0bd30201067f230041206b22042400024020002001460d00200141046a21062001280200210102402000280208450d00200028020021032000200041046a3602002000410036020820002802042102200041003602042002410036020820032802042202200320021b2102034020022203450d0120012006470440200341106a200141106a10252107024020032802082202450440410021020c010b2003200228020022054604402002410036020020022802042205450d012005104921020c010b200241003602042005450d002005104921020b2000200441106a2007104a2107200020042802102007200310452001103021010c010b0b0340200328020822030d000b200621010b034020012006460d01200441106a2000200141106a104420002004410c6a2004280210220341106a104a21022000200428020c2002200310452001103021010c000b000b200441206a24000bd60101067f230041106b22022400200042003702042000200041046a2203360200200141046a21062001280200210103402001200646450440200141106a21050240027f027f0240024020032000280200460440200321040c010b20031041220441106a20051042450d010b20032802004504402002200336020c2003210420030c030b2002200436020c200441046a0c010b20002002410c6a200510430b22042802000d01200228020c0b21072002200020051044200020072004200228020010450b2001103021010c010b0b200241106a240020000bfc0801067f03400240200020046a2105200120046a210320022004460d002003410371450d00200520032d00003a0000200441016a21040c010b0b200220046b210602402005410371220745044003402006411049450440200020046a2203200120046a2205290200370200200341086a200541086a290200370200200441106a2104200641706a21060c010b0b027f2006410871450440200120046a2103200020046a0c010b200020046a2205200120046a2204290200370200200441086a2103200541086a0b21042006410471044020042003280200360200200341046a2103200441046a21040b20064102710440200420032f00003b0000200341026a2103200441026a21040b2006410171450d01200420032d00003a000020000f0b024020064120490d002007417f6a220741024b0d00024002400240024002400240200741016b0e020102000b2005200120046a220328020022073a0000200541016a200341016a2f00003b0000200041036a2108200220046b417d6a2106034020064111490d03200420086a2203200120046a220541046a2802002202410874200741187672360200200341046a200541086a2802002207410874200241187672360200200341086a2005410c6a28020022024108742007411876723602002003410c6a200541106a2802002207410874200241187672360200200441106a2104200641706a21060c000b000b2005200120046a220328020022073a0000200541016a200341016a2d00003a0000200041026a2108200220046b417e6a2106034020064112490d03200420086a2203200120046a220541046a2802002202411074200741107672360200200341046a200541086a2802002207411074200241107672360200200341086a2005410c6a28020022024110742007411076723602002003410c6a200541106a2802002207411074200241107672360200200441106a2104200641706a21060c000b000b2005200120046a28020022073a0000200041016a21082004417f7320026a2106034020064113490d03200420086a2203200120046a220541046a2802002202411874200741087672360200200341046a200541086a2802002207411874200241087672360200200341086a2005410c6a28020022024118742007410876723602002003410c6a200541106a2802002207411874200241087672360200200441106a2104200641706a21060c000b000b200120046a41036a2103200020046a41036a21050c020b200120046a41026a2103200020046a41026a21050c010b200120046a41016a2103200020046a41016a21050b20064110710440200520032d00003a00002005200328000136000120052003290005370005200520032f000d3b000d200520032d000f3a000f200541106a2105200341106a21030b2006410871044020052003290000370000200541086a2105200341086a21030b2006410471044020052003280000360000200541046a2105200341046a21030b20064102710440200520032f00003b0000200541026a2105200341026a21030b2006410171450d00200520032d00003a00000b20000b2b01027f200141046a210203402002280200220341046a210220012003470d000b200041a80b6a2001103e0bbe0201057f024020002001460d00200041046a2102200141046a21030340200228020021020240027f4101200328020022032001460d001a20002002470d0141000b210402402000200246044020040d044114104022054100360200200541086a200341086a10181a20052104410121060340200120032802042203460d0241141040220241086a200341086a10181a2002200436020020042002360204200641016a2106200221040c000b000b200228020022032000280200220128020436020420012802042003360200034020002002460d0420002000280208417f6a360208200228020421020c000b000b2000280200220220053602042005200236020020002004360200200420003602042000200028020820066a3602080c020b200241086a200341086a10251a200241046a2102200341046a21030c000b000b0b840101037f200041003602082000200036020420002000360200200141046a2102037f20022802002203200146047f2000054114104022024100360200200241086a200341086a10181a20022000360204200028020021042000200236020020022004360200200420023602042000200028020841016a360208200341046a21020c010b0b0b0b002000410120001b10670b3e01027f024020002802002201044003402001220228020422010d000c020b000b03402000280208220228020020004621012002210020010d000b0b20020bb20101067f02400240200128020420012d00002202410176200241017122031b2205200028020420002d00002202410176200241017122041b2206200520064922071b2202450d002000280208200041016a20041b21002001280208200141016a20031b210103402002450d0120002d0000220320012d00002204460440200141016a2101200041016a21002002417f6a21020c010b0b200320046b22020d010b417f200720062005491b21020b2002411f760b890101027f200041046a2103024020002802042200044002400340024002402002200041106a220410420440200028020022040d012001200036020020000f0b200420021042450d03200041046a210320002802042204450d01200321000b20002103200421000c010b0b2001200036020020030f0b200120003602000c010b200120033602000b20030b2d01017f2000411c104022033602002000200141046a360204200341106a200210181a200041086a41013a00000b480020032001360208200342003702002002200336020020002802002802002201044020002001360200200228020021030b2000280204200310462000200028020841016a3602080bec0101037f200120002001463a000c03400240024020002001460d00200128020822022d000c0d002002200228020822032802002204460440024020032802042204450d0020042d000c0d002004410c6a21010c030b20012002280200470440200210472002280208220228020821030b200241013a000c200341003a000c200310480f0b02402004450d0020042d000c0d002004410c6a21010c020b20012002280200460440200210482002280208220228020821030b200241013a000c200341003a000c200310470b0f0b200241013a000c200320002003463a000c200141013a0000200321010c000b000b5101027f200020002802042201280200220236020420020440200220003602080b200120002802083602082000280208220220022802002000474102746a200136020020002001360208200120003602000b5101027f200020002802002201280204220236020020020440200220003602080b200120002802083602082000280208220220022802002000474102746a200136020020002001360208200120003602040b1d01017f03402000220128020022000d00200128020422000d000b20010b5c01017f0240200028020422030440034002402002200341106a1042044020032802002200450d040c010b200328020422000d0020012003360200200341046a0f0b200021030c000b000b200041046a21030b2001200336020020030b2001017f2000200110402202360200200020023602042000200120026a3602080b2800200120006b220141014e0440200228020020002001103c1a2002200228020020016a3602000b0b1900200120006b22010440200220002001104f0b200120026a0b2e01017f2001200028020820002802006b2200410174220220022001491b41ffffffff07200041ffffffff03491b0b8d0301037f024020002001460d00200120006b20026b410020024101746b4d0440200020012002103c1a0c010b20002001734103712103027f024020002001490440200020030d021a410021030340200120036a2105200020036a2204410371450440200220036b210241002103034020024104490d04200320046a200320056a280200360200200341046a21032002417c6a21020c000b000b20022003460d04200420052d00003a0000200341016a21030c000b000b024020030d002001417f6a21040340200020026a22034103714504402001417c6a21032000417c6a2104034020024104490d03200220046a200220036a2802003602002002417c6a21020c000b000b2002450d042003417f6a200220046a2d00003a00002002417f6a21020c000b000b2001417f6a210103402002450d03200020026a417f6a200120026a2d00003a00002002417f6a21020c000b000b200320056a2101200320046a0b210303402002450d01200320012d00003a00002002417f6a2102200341016a2103200141016a21010c000b000b0b2c01017f20004128104022033602002000200141046a360204200341106a20021051200041086a41013a00000b16002000200110181a2000410c6a2001410c6a10181a0b2301017f2000200110532202360200200020023602042000200220014101746a3602080b0900200041017410400b2501017f200120006b2201410175210320010440200220002001104f0b200220034101746a0b2a002001200028020820002802006b220020002001491b41ffffffff07200041017541ffffffff03491b0b5b01027f02402002410a4d0440200020024101743a0000200041016a21030c010b200241106a4170712204104021032000200236020420002004410172360200200020033602080b20032001200210cc01200220036a41003a00000b1600200041003602082000420037020020004100105c0bdd0101047f024020002802042203200028020022026b22042001490440200028020820036b200120046b22024f04400340200341003a00002000200028020441016a22033602042002417f6a22020d000c030b000b20002001104e220104402001104021050b200420056a220421030340200341003a0000200341016a21032002417f6a22020d000b200120056a210520042000280204200028020022046b22016b2102200141014e0440200220042001103c1a0b2000200536020820002003360204200020023602000f0b200420014d0d002000200120026a3602040b0b1e01017f03402000044020004108762100200141016a21010c010b0b20010b25002000200120026a417f6a220241087641fcffff07716a280200200241ff07714102746a0b900101027f4101210420014280015441002002501b450440034020012002845045044020024238862001420888842101200341016a2103200242088821020c010b0b200341384f047f2003105920036a0520030b41016a21040b027f200041186a28020022030440200041086a280200200041146a2802002003105a0c010b20000b2203200328020020046a36020020000b2f01017f200028020820014904402001106720002802002000280204103c210220002001360208200020023602000b0b2c01017f2000200120021004200028020422036a10d30120012002200320002802006a1005200010d20120000b2a01017f2000200220011006200028020422036a10d30120022001200320002802006a1007200010d2010b2801017f200028020820002802046b2201410874417f6a410020011b200028021420002802106a6b0b2501017f200028020821020340200120024645044020002002417c6a22023602080c010b0b0ba10202057f017e230041206b22052400024020002802082202200028020c2203470d0020002802042204200028020022064b04402000200420022004200420066b41027541016a417e6d41027422036a106222023602082000200028020420036a3602040c010b200541086a200320066b2202410175410120021b220220024102762000410c6a10632103200028020821042000280204210203402002200446450440200328020820022802003602002003200328020841046a360208200241046a21020c010b0b20002902002107200020032902003702002003200737020020002902082107200020032902083702082003200737020820031064200028020821020b200220012802003602002000200028020841046a360208200541206a24000b2501017f200120006b2201410275210320010440200220002001104f0b200220034102746a0b4f01017f2000410036020c200041106a2003360200200104402001410274104021040b200020043602002000200420024102746a22023602082000200420014102746a36020c2000200236020420000b2b01027f200028020821012000280204210203402001200247044020002001417c6a22013602080c010b0b0b1b00200120006b22010440200220016b220220002001104f0b20020b4f01037f20012802042203200128021020012802146a220441087641fcffff07716a21022000027f410020032001280208460d001a2002280200200441ff07714102746a0b360204200020023602000b9b0101047f230041106b220124002001200036020c2000047f41880c200041086a2202411076220041880c2802006a220336020041840c41840c280200220420026a41076a417871220236020002400240200341107420024d044041880c200341016a360200200041016a21000c010b2000450d010b200040000d0010000b20042001410c6a4104103c41086a0541000b2100200141106a240020000b090010cb011069106a0be82602057f027e230041c0166b2201240010082200106722021009200141d00a6a200141086a20022000106b22004100106c02400240200141d00a6a106d2205500d0041c208106e20055104402000106f200141d00a6a107010710c020b41c708106e200551044020001072410247044010000b200141d00a6a20004101106c200141d00a6a10732100200141d00a6a1070220220001022200210710c020b41d008106e20055104402000106f200141d00a6a107022032d00102102200141b8086a10172200200210741015200020021020200028020c200041106a28020047044010000b20002802002000280204100e200028020c22020440200020023602100b200310710c020b41d908106e200551044020001072410247044010000b200141d00a6a20004101106c200141d00a6a10752100200141d00a6a1070220220001023200210710c020b41e308106e20055104402000106f200141d00a6a1070220341286a2f01002102200141b8086a10172200200210761015200020021020200028020c200041106a28020047044010000b20002802002000280204100e200028020c22020440200020023602100b200310710c020b41ed08106e200551044020001072410247044010000b200141d00a6a20004101106c200141d00a6a10772100200141d00a6a1070220220001024200210710c020b41f708106e20055104402000106f200141d00a6a1070220341406b2802002102200141b8086a10172200200210781015200020021020200028020c200041106a28020047044010000b20002802002000280204100e200028020c22020440200020023602100b200310710c020b418109106e200551044020001072410247044010000b200141d00a6a20004101106c200141d00a6a106d2105200141d00a6a1070220041d8006a2005370300200010710c020b418b09106e20055104402000106f200141d00a6a1070220241d8006a2903002105200141b8086a1017220020051079101520002005107a200028020c200041106a28020047044010000b20002802002000280204100e200028020c22030440200020033602100b200210710c020b419509106e2005510440200141b8066a107b210220001072410247044010000b200141d00a6a20004101106c200141d00a6a2002107c200141d00a6a1070220041f8006a200141b8086a2002101810251a200010710c020b419f09106e20055104402000106f200141a0046a200141d00a6a1070220241f8006a10182100200141b8086a101722032000107d10152003200141b8066a20001018101d220028020c200041106a28020047044010000b20002802002000280204100e200028020c22030440200020033602100b200210710c020b41a909106e2005510440200141003a00b80820001072410247044010000b200141d00a6a20004101106c200141d00a6a200141b8086a107e200141d00a6a107022004198016a20012d00b8083a0000200010710c020b41b109106e20055104402000106f200141d00a6a107022034198016a2d00002102200141b8086a10172200200210741015200020021020200028020c200041106a28020047044010000b20002802002000280204100e200028020c22020440200020023602100b200310710c020b41b909106e200551044020004101107f0c020b41c109106e2005510440200041021080010c020b41c909106e2005510440200141b8066a10810120001072410247044010000b200141d00a6a20004101106c200141d00a6a200141b8066a108201200141d00a6a1070220041d0016a200141b8086a200141b8066a101810251a200010710c020b41d409106e20055104402000106f200141b8066a200141d00a6a1070220241d0016a10181a200141b8086a10172200200141b8066a10830110152000200141b8066a108401200028020c200041106a28020047044010000b20002802002000280204100e200028020c22030440200020033602100b200210710c020b41df09106e2005510440200141b8066a41241085011a200141b8066a108601210220001072410247044010000b200141d00a6a20004101106c200141d00a6a2002108701200141d00a6a107022004190026a200141b8086a200210291028200010710c020b41ec09106e20055104402000106f200141b8086a200141d00a6a107022034190026a10292102200141b8066a101722002002108801101520002002108901200028020c200041106a28020047044010000b20002802002000280204100e200028020c22020440200020023602100b200310710c020b41f909106e200551044020004103107f0c020b41810a106e2005510440200041041080010c020b41890a106e200551044020001072410247044010000b200141d00a6a20004101106c200141d00a6a108a012100200141d00a6a1070220241e0026a20003b0100200210710c020b41920a106e20055104402000106f200141d00a6a1070220341e0026a2e01002102200141b8086a101722002002108b01101520002002108c01200028020c200041106a28020047044010000b20002802002000280204100e200028020c22020440200020023602100b200310710c020b419b0a106e200551044020001072410247044010000b200141d00a6a20004101106c200141d00a6a108d012100200141d00a6a1070220241f8026a2000360200200210710c020b41a40a106e20055104402000106f200141d00a6a1070220341f8026a2802002102200141b8086a101722002002108e01101520002002108c01200028020c200041106a28020047044010000b20002802002000280204100e200028020c22020440200020023602100b200310710c020b41ad0a106e200551044020001072410247044010000b200141d00a6a20004101106c200141d00a6a108f012105200141d00a6a107022004190036a2005370300200010710c020b41b60a106e20055104402000106f200141d00a6a107022024190036a2903002105200141b8086a101722002005109001101520002005109101200028020c200041106a28020047044010000b20002802002000280204100e200028020c22030440200020033602100b200210710c020b41bf0a106e2005510440200141003602c006200142003703b80620001072410247044010000b200141d00a6a20004101106c200141d00a6a200141b8066a109201200141d00a6a1070220241e0036a200141b8086a200141b8066a102d2200102c200028020022030440200020033602040b2002107120012802b8062200450d02200120003602bc060c020b41c90a106e20055104402000106f200141b8066a200141d00a6a1070220341e0036a102d2102200141b8086a101722002002109301101520002002109401200028020c200041106a28020047044010000b20002802002000280204100e200028020c22040440200020043602100b200228020022000440200220003602040b200310710c020b41d30a106e2005510440200142003702bc062001200141b8066a4104723602b80620001072410247044010000b200141d00a6a20004101106c200141d00a6a200141b8066a109501200141d00a6a10702200200141b8086a200141b8066a1031102e200010710c020b41da0a106e20055104402000106f200141b8066a200141d00a6a107022034188046a10312102200141b8086a101722002002109601101520002002109701200028020c200041106a28020047044010000b20002802002000280204100e200028020c22020440200020023602100b200310710c020b41e10a106e2005510440200141b8086a108101200141003a00c808200141003602c408200141c8086a210220001072410447044010000b200141d00a6a20004101106c200141d00a6a200141b8086a108201200141d00a6a20004102106c2001200141d00a6a108d013602c408200141d00a6a20004103106c200141d00a6a2002107e200141d00a6a10702100200141b8066a200141b8086a10181a2000200141b8066a20012802c40820012d00c8081032200010710c020b41f10a106e2005510440200141003602a804200142003703a00420001072410247044010000b200141d00a6a20004101106c200141d00a6a200141a0046a109801200141d00a6a1070220341b0046a200141b8086a200141b8066a200141a0046a10342200103422021033200228020022040440200220043602040b200028020022020440200020023602040b2003107120012802a0042200450d02200120003602a4040c020b41fa0a106e20055104402000106f200141b8066a200141d00a6a1070220341b0046a10342102200141b8086a10172200200228020020022802041099011015200020021016200028020c200041106a28020047044010000b20002802002000280204100e200028020c22040440200020043602100b200228020022000440200220003602040b200310710c020b41830b106e2005510440200141b8066a41f8001085011a200141b8066a109a01210220001072410247044010000b200141d00a6a20004101106c200141d00a6a2002109b01200141d00a6a1070220041c0056a200141b8086a200210361035200010710c020b418c0b106e20055104402000106f200141b8086a200141d00a6a1070220341c0056a10362102200141b8066a101722002002109c01101520002002109d01200028020c200041106a28020047044010000b20002802002000280204100e200028020c22020440200020023602100b200310710c020b41950b106e2005510440200141b8066a109e01210220001072410247044010000b200141d00a6a20004101106c200141d00a6a2002109f01200141d00a6a1070220041d0066a200141b8086a200210381037200010710c020b419d0b106e20055104402000106f200141b8066a200141d00a6a1070220341d0066a10382102200141b8086a10172200200210a00110152000200210a101200028020c200041106a28020047044010000b20002802002000280204100e200028020c22020440200020023602100b200310710c020b41a50b106e2005510440200142003702bc062001200141b8066a4104723602b80620001072410247044010000b200141d00a6a20004101106c200141d00a6a200141b8066a10a201200141d00a6a10702200200141b8086a200141b8066a103b1039200010710c020b41ac0b106e20055104402000106f200141b8066a200141d00a6a1070220341f8066a103b2102200141b8086a10172200200210a30110152000200210a401200028020c200041106a28020047044010000b20002802002000280204100e200028020c22020440200020023602100b200310710c020b41b30b106e2005510440200141b8066a4180021085011a20001072410247044010000b200141d00a6a20004101106c200141d00a6a200141b8066a10a501200141d00a6a10702100200141206a200141b8066a418002103c1a200141b8086a200141206a418002103c1a20004190096a200141b8086a418002103c1a200010710c020b41c00b106e20055104402000106f200141a0026a200141d00a6a107022024190096a418002103c1a200141a0066a10172200200141a0026a10a6011015200141a0046a200141a0026a418002103c1a200141b8066a200141a0046a418002103c1a200141206a200141b8066a418002103c1a200141b8086a200141206a418002103c1a2000200141b8086a418002105d220028020c200041106a28020047044010000b20002802002000280204100e200028020c22030440200020033602100b200210710c020b41cd0b106e2005510440200141003602c0062001200141b8066a3602bc062001200141b8066a3602b80620001072410247044010000b200141d00a6a20004101106c200141d00a6a200141b8066a10a701200141d00a6a10702200200141b8086a200141b8066a103f2202103d200210a80120001071200141b8066a10a8010c020b41d50b106e20055104402000106f200141b8066a200141d00a6a1070220341a80b6a103f2102200141b8086a10172200200210a90110152000200210aa01200028020c200041106a28020047044010000b20002802002000280204100e200028020c22040440200020043602100b200210a801200310710c020b41dd0b106e2005510440200141c8086a22024100360200200141c0086a22034200370300200142003703b80820001072410247044010000b200141d00a6a20004101106c200141d00a6a200141b8086a10ab01200141d00a6a10702100200141b0066a20022802002202360200200141a8066a20032903002205370300200120012903b80822063703a006200041d80b6a2006370300200041e00b6a2005370300200041e80b6a2002360200200010710c020b41e80b106e2005520d002000106f200141306a2200200141d00a6a1070220241e80b6a280000360200200141286a2203200241e00b6a2900003703002001200241d80b6a290000370320200141b8086a10172204200141206a10ac011015200141b0026a20002802002200360200200141a8026a200329030022053703002001200129032022063703a002200141a8046a2005370300200141b0046a2000360200200141a8066a2005370300200141b0066a2000360200200120063703a004200120063703a006200141c8066a2000360200200141c0066a2005370300200120063703b8062004200141b8066a4114105d220028020c200041106a28020047044010000b20002802002000280204100e200028020c22030440200020033602100b200210710c010b10000b200141c0166a24000b880101037f41f40b410136020041f80b2802002100034020000440034041fc0b41fc0b2802002201417f6a2202360200200141014845044041f40b4100360200200020024102746a22004184016a280200200041046a28020011030041f40b410136020041f80b28020021000c010b0b41fc0b412036020041f80b200028020022003602000c010b0b0b0d00200020012002411c10ad010bd00202067f017e230041106b220324002001280208220520024b0440200341086a200110d10120012003280208200328020c10cf0136020c2003200110d101410021052001027f410020032802002207450d001a410020032802042208200128020c2206490d001a200820062006417f461b210420070b360210200141146a2004360200200141003602080b200141106a210603402001280214210402402005200249044020040d01410021040b200020062802002004411410ad011a200341106a24000f0b2003200110d10141002104027f410020032802002205450d001a410020032802042208200128020c2207490d001a200820076b2104200520076a0b210520012004360214200120053602102003200641002005200410cf0110d0012001200329030022093702102001200128020c2009422088a76a36020c2001200128020841016a22053602080c000b000b880102027f017e230041106b22012400200010ae0102400240200010af01450d002000280204450d0020002802002d000041c001490d010b10000b200141086a200010b001200128020c220041094f044010000b200128020821020340200004402000417f6a210020023100002003420886842103200241016a21020c010b0b200141106a240020030b3901027e42a5c688a1c89ca7f94b210103402000300000220250450440200041016a2100200142b383808080207e20028521010c010b0b20010b0e0020001072410147044010000b0bf42901097f230041406a22012400200042ddbe888dc5fcfca4987f370308200041003a0000200141286a101722032000290308107a200328020c200341106a28020047044010000b02402003280200220720032802042208100a2205450d002001410036022020014200370318200141186a200510582007200820012802182202200128021c220620026b100b417f47044020002001200241016a20062002417f736a106b10733a0010200521040b2002450d002001200236021c0b200328020c22020440200320023602100b2004450440200020002d00003a00100b41002104200041003b0118200041206a220242debe888dc5fcfca4987f370300200141286a101722032002290300107a200328020c200341106a28020047044010000b02402003280200220720032802042208100a2205450d002001410036022020014200370318200141186a200510582007200820012802182202200128021c220620026b100b417f47044020002001200241016a20062002417f736a106b10753b0128200521040b2002450d002001200236021c0b200328020c22020440200320023602100b2004450440200020002f01183b01280b4100210420004100360230200041386a220242dfbe888dc5fcfca4987f370300200141286a101722032002290300107a200328020c200341106a28020047044010000b02402003280200220720032802042208100a2205450d002001410036022020014200370318200141186a200510582007200820012802182202200128021c220620026b100b417f47044020002001200241016a20062002417f736a106b1077360240200521040b2002450d002001200236021c0b200328020c22020440200320023602100b2004450440200020002802303602400b20004200370348200041d0006a220442d9be888dc5fcfca4987f370300200141286a101722032004290300107a200328020c200341106a28020047044010000b02402003280200220720032802042208100a2205450440410021020c010b410021022001410036022020014200370318200141186a200510582007200820012802182204200128021c220620046b100b417f47044020002001200441016a20062004417f736a106b106d370358200521020b2004450d002001200436021c0b200328020c22040440200320043602100b2002450440200020002903483703580b200041e0006a107b2109200041f0006a220442a7cea8ad82a0ff995b370300200041f8006a107b2107200141286a101722032004290300107a200328020c200341106a28020047044010000b02402003280200220820032802042206100a2205450440410021020c010b410021022001410036022020014200370318200141186a200510582008200620012802182204200128021c220620046b100b417f4704402001200441016a20062004417f736a106b2007107c200521020b2004450d002001200436021c0b200328020c22040440200320043602100b20024504402007200910251a0b41002104200041003a00880120004190016a220242f4a2efb3f6e5b8ad03370300200141286a101722032002290300107a200328020c200341106a28020047044010000b02402003280200220720032802042208100a2205450d002001410036022020014200370318200141186a200510582007200820012802182202200128021c220620026b100b417f4704402001200241016a20062002417f736a106b20004198016a107e200521040b2002450d002001200236021c0b200328020c22020440200320023602100b2004450440200020002d0088013a0098010b200041003a00a001200041a8016a220342badda0b2f6c5fa8e033703002003200041b0016a10b101450440200020002d00a0013a00b0010b200042003703b801200041c0016a4100360200200041b8016a107b2109200041c8016a2204428aedabfdf7a698fe29370300200041d0016a2207107b1a200141286a101722032004290300107a200328020c200341106a28020047044010000b02402003280200220820032802042206100a2205450440410021020c010b410021022001410036022020014200370318200141186a200510582008200620012802182204200128021c220620046b100b417f4704402001200441016a20062004417f736a106b2007108201200521020b2004450d002001200436021c0b200328020c22040440200320043602100b20024504402007200910251a0b41002104200041e0016a4124108501108601210920004188026a220242d4b7b1edebf7e3f66a37030020004190026a1086012107200141286a101722032002290300107a200328020c200341106a28020047044010000b02402003280200220820032802042206100a2205450d002001410036022020014200370318200141186a200510582008200620012802182202200128021c220620026b100b417f4704402001200241016a20062002417f736a106b2007108701200521040b2002450d002001200236021c0b200328020c22020440200320023602100b20044504402007200910280b200041003a00b802200041c0026a220342ccacbdb4f8a587a93d3703002003200041c8026a10b101450440200020002d00b8023a00c8020b200041003b01d002200041d8026a220442cfacbdb4f8a587a93d370300200141286a101722032004290300107a200328020c200341106a28020047044010000b02402003280200220720032802042208100a2205450440410021020c010b410021022001410036022020014200370318200141186a200510582007200820012802182204200128021c220620046b100b417f47044020002001200441016a20062004417f736a106b108a013b01e002200521020b2004450d002001200436021c0b200328020c22040440200320043602100b2002450440200020002f01d0023b01e0020b41002104200041003602e802200041f0026a220242ceacbdb4f8a587a93d370300200141286a101722032002290300107a200328020c200341106a28020047044010000b02402003280200220720032802042208100a2205450d002001410036022020014200370318200141186a200510582007200820012802182202200128021c220620026b100b417f47044020002001200241016a20062002417f736a106b108d013602f802200521040b2002450d002001200236021c0b200328020c22020440200320023602100b2004450440200020002802e8023602f8020b200042003703800320004188036a220442c8acbdb4f8a587a93d370300200141286a101722032004290300107a200328020c200341106a28020047044010000b02402003280200220720032802042208100a2205450440410021020c010b410021022001410036022020014200370318200141186a200510582007200820012802182204200128021c220620046b100b417f47044020002001200441016a20062004417f736a106b108f0137039003200521020b2004450d002001200436021c0b200328020c22040440200320043602100b20024504402000200029038003370390030b410021042000410036029803200041a0036a220242e2e780dbeae4fcabe100370300200141286a101722032002290300107a200328020c200341106a28020047044010000b02402003280200220720032802042208100a2205450d002001410036022020014200370318200141186a200510582007200820012802182202200128021c220620026b100b417f47044020002001200241016a20062002417f736a106b10773602a803200521040b2002450d002001200236021c0b200328020c22020440200320023602100b200445044020002000280298033602a8030b200042003703b003200041b8036a220442b3debf9dbddf9ca832370300200141286a101722032004290300107a200328020c200341106a28020047044010000b02402003280200220720032802042208100a2205450440410021020c010b410021022001410036022020014200370318200141186a200510582007200820012802182204200128021c220620046b100b417f47044020002001200441016a20062004417f736a106b106d3703c003200521020b2004450d002001200436021c0b200328020c22040440200320043602100b2002450440200020002903b0033703c0030b200042003702c80341002104200041e8036a4100360200200041e0036a22074200370200200041d8036a2202429fe6c89bc186c5be1d370300200041d0036a4100360200200141286a101722032002290300107a200328020c200341106a28020047044010000b02402003280200220820032802042206100a2205450d002001410036022020014200370318200141186a200510582008200620012802182202200128021c220920026b100b417f4704402001200241016a20092002417f736a106b2007109201200521040b2002450d002001200236021c0b200328020c22020440200320023602100b20044504402007200041c8036a102c0b200041f4036a220342003702002000418c046a2204420037020020004180046a2202428cbcadf0bacdb08975370300200020033602f00320004188046a22072004360200200141286a101722032002290300107a200328020c200341106a28020047044010000b02402003280200220820032802042206100a2205450440410021020c010b410021022001410036022020014200370318200141186a200510582008200620012802182204200128021c220920046b100b417f4704402001200441016a20092004417f736a106b2007109501200521020b2004450d002001200436021c0b200328020c22040440200320043602100b20024504402007200041f0036a102f0b200042003702980441002104200041b8046a4100360200200041b0046a22074200370200200041a8046a220242bd8ce2969cacfba4b07f370300200041a0046a4100360200200141286a101722032002290300107a200328020c200341106a28020047044010000b02402003280200220820032802042206100a2205450d002001410036022020014200370318200141186a200510582008200620012802182202200128021c220920026b100b417f4704402001200241016a20092002417f736a106b2007109801200521040b2002450d002001200236021c0b200328020c22020440200320023602100b2004450440200720004198046a10330b41002104200041c0046a41f800108501109a012109200041b8056a2202429fa88ce0a0829ecea47f370300200041c0056a109a012107200141286a101722032002290300107a200328020c200341106a28020047044010000b02402003280200220820032802042206100a2205450d002001410036022020014200370318200141186a200510582008200620012802182202200128021c220620026b100b417f4704402001200241016a20062002417f736a106b2007109b01200521040b2002450d002001200236021c0b200328020c22020440200320023602100b20044504402007200910350b200041b8066a109e012109200041c8066a220442bcf8d4f484c7a18d807f370300200041d0066a109e012107200141286a101722032004290300107a200328020c200341106a28020047044010000b02402003280200220820032802042206100a2205450440410021020c010b410021022001410036022020014200370318200141186a200510582008200620012802182204200128021c220620046b100b417f4704402001200441016a20062004417f736a106b2007109f01200521020b2004450d002001200436021c0b200328020c22040440200320043602100b20024504402007200910370b200041e4066a22034200370200200041fc066a22044200370200200041f0066a220242eafdbbb690ac81edca00370300200020033602e006200041f8066a22072004360200200141286a101722032002290300107a200328020c200341106a28020047044010000b02402003280200220820032802042206100a2205450440410021020c010b410021022001410036022020014200370318200141186a200510582008200620012802182204200128021c220920046b100b417f4704402001200441016a20092004417f736a106b200710a201200521020b2004450d002001200436021c0b200328020c22040440200320043602100b20024504402007200041e0066a103a0b4100210420004188076a418002108501210920004188096a220242d0b4afbcbf988ce0b77f37030020004190096a4180021085012107200141286a101722032002290300107a200328020c200341106a28020047044010000b02402003280200220820032802042206100a2205450d002001410036022020014200370318200141186a200510582008200620012802182202200128021c220620026b100b417f4704402001200241016a20062002417f736a106b200710a501200521040b2002450d002001200236021c0b200328020c22020440200320023602100b200445044020072009418002103c1a0b41002102200041b00b6a4100360200200041ac0b6a200041a80b6a2204360200200041a00b6a220542f4ffce959b97c9c1d500370300200041980b6a4100360200200041940b6a200041900b6a2207360200200020073602900b20042004360200200141286a101722032005290300107a200328020c200341106a28020047044010000b02402003280200220620032802042209100a2208450d002001410036022020014200370318200141186a200810582006200920012802182205200128021c220620056b100b417f4704402001200541016a20062005417f736a106b200410a701200821020b2005450d002001200536021c0b200328020c22050440200320053602100b200245044020042007103e0b200042003700b80b41002104200041c80b6a4100360000200041c00b6a4200370000200041d80b6a22054200370000200041d00b6a220242affad78bbfdecaa6f300370300200041e00b6a4200370000200041e80b6a4100360000200141286a101722032002290300107a200328020c200341106a28020047044010000b02402003280200220820032802042206100a2207450d002001410036022020014200370318200141186a200710582008200620012802182202200128021c220920026b100b417f4704402001200241016a20092002417f736a106b200510ab01200721040b2002450d002001200236021c0b200328020c22020440200320023602100b20044504402005200041b80b6a2203290300370300200541106a200341106a280200360200200541086a200341086a2903003703000b200141406b240020000b973102087f027e230041c0086b22052400200541c0066a10172201200041d00b6a22022903001079101520012002290300107a200041d80b6a2102200128020c200141106a28020047044010000b2001280204210720012802002106200541c0046a10172104200210ac012108200420054180026a10b201220310b3012004200820032802046a20032802006b1015200541a0026a200241106a280000220836020020054198026a200241086a290000220937030020052002290000220a37039002200541b0026a2009370300200541b8026a2008360200200541086a2009370300200541106a20083602002005200a3703a8022005200a370300200541d0026a2008360200200541c8026a20093703002005200a3703c00202402004200541c0026a4114105d220228020c200241106a280200460440200241046a2104200228020021080c010b200241046a2104100020022802002108200228020c2002280210460d0010000b2006200720082004280200100c200328020022040440200320043602040b200228020c22030440200220033602100b200128020c22020440200120023602100b200541c0066a10172202200041a00b6a22012903001079101520022001290300107a200041a80b6a2104200228020c200241106a28020047044010000b2002280204210820022802002107200541c0046a10172101200410a90121062001200541c0026a10b201220310b3012001200620032802046a20032802006b10152001200410aa010240200128020c200141106a280200460440200141046a2104200128020021060c010b200141046a2104100020012802002106200128020c2001280210460d0010000b2007200820062004280200100c200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200041a80b6a10a801200041900b6a10a801200541a8026a1017220120004188096a22022903001079101520012002290300107a20004190096a2104200128020c200141106a28020047044010000b200128020421082001280200210720054190026a10172102200410a6012106200220054180026a10b201220310b3012002200620032802046a20032802006b101520052004418002103c220541c0026a2005418002103c1a200541c0046a200541c0026a418002103c1a200541c0066a200541c0046a418002103c1a02402002200541c0066a418002105d220228020c200241106a280200460440200241046a2104200228020021060c010b200241046a2104100020022802002106200228020c2002280210460d0010000b2007200820062004280200100c200328020022040440200320043602040b200228020c22030440200220033602100b200128020c22020440200120023602100b200541c0066a10172202200041f0066a22012903001079101520022001290300107a200041f8066a2104200228020c200241106a28020047044010000b2002280204210820022802002107200541c0046a10172101200410a30121062001200541c0026a10b201220310b3012001200620032802046a20032802006b10152001200410a4010240200128020c200141106a280200460440200141046a2104200128020021060c010b200141046a2104100020012802002106200128020c2001280210460d0010000b2007200820062004280200100c200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a10172202200041c8066a22012903001079101520022001290300107a200041d0066a2104200228020c200241106a28020047044010000b2002280204210820022802002107200541c0046a10172101200410a00121062001200541c0026a10b201220310b3012001200620032802046a20032802006b10152001200410a1010240200128020c200141106a280200460440200141046a2104200128020021060c010b200141046a2104100020012802002106200128020c2001280210460d0010000b2007200820062004280200100c200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a10172202200041b8056a22012903001079101520022001290300107a200041c0056a2104200228020c200241106a28020047044010000b2002280204210820022802002107200541c0046a101721012004109c0121062001200541c0026a10b201220310b3012001200620032802046a20032802006b101520012004109d010240200128020c200141106a280200460440200141046a2104200128020021060c010b200141046a2104100020012802002106200128020c2001280210460d0010000b2007200820062004280200100c200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a10172202200041a8046a22012903001079101520022001290300107a200041b0046a2104200228020c200241106a28020047044010000b2002280204210820022802002107200541c0046a1017210120002802b004200041b4046a28020010990121062001200541c0026a10b201220310b3012001200620032802046a20032802006b10152001200410160240200128020c200141106a280200460440200141046a2104200128020021060c010b200141046a2104100020012802002106200128020c2001280210460d0010000b2007200820062004280200100c200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200041b0046a28020022010440200041b4046a20013602000b200028029804220104402000419c046a20013602000b200541c0066a1017220220004180046a22012903001079101520022001290300107a20004188046a2104200228020c200241106a28020047044010000b2002280204210820022802002107200541c0046a10172101200410960121062001200541c0026a10b201220310b3012001200620032802046a20032802006b1015200120041097010240200128020c200141106a280200460440200141046a2104200128020021060c010b200141046a2104100020012802002106200128020c2001280210460d0010000b2007200820062004280200100c200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a10172202200041d8036a22012903001079101520022001290300107a200041e0036a2104200228020c200241106a28020047044010000b2002280204210820022802002107200541c0046a10172101200410930121062001200541c0026a10b201220310b3012001200620032802046a20032802006b1015200120041094010240200128020c200141106a280200460440200141046a2104200128020021060c010b200141046a2104100020012802002106200128020c2001280210460d0010000b2007200820062004280200100c200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200041e0036a28020022010440200041e4036a20013602000b20002802c80322010440200041cc036a20013602000b200541c0046a10172202200041b8036a22012903001079101520022001290300107a200228020c200241106a28020047044010000b2002280204210420022802002108200541c0026a10172101200541d8066a4100360200200541d0066a4200370300200541c8066a4200370300200542003703c006200541c0066a20002903c00310b40120052802c0062107200541c0066a410472101b2001200541c0066a10b201220310b3012001200720032802046a20032802006b1015200120002903c003107a0240200128020c200141106a280200460440200141046a2107200128020021060c010b200141046a2107100020012802002106200128020c2001280210460d0010000b2008200420062007280200100c200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0046a10172202200041a0036a22012903001079101520022001290300107a200228020c200241106a28020047044010000b2002280204210420022802002108200541c0026a10172101200541d8066a4100360200200541d0066a4200370300200541c8066a4200370300200542003703c006200541c0066a20002802a803101f20052802c0062107200541c0066a410472101b2001200541c0066a10b201220310b3012001200720032802046a20032802006b1015200120002802a80310200240200128020c200141106a280200460440200141046a2107200128020021060c010b200141046a2107100020012802002106200128020c2001280210460d0010000b2008200420062007280200100c200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a1017220220004188036a22012903001079101520022001290300107a200228020c200241106a28020047044010000b2002280204210420022802002108200541c0046a1017210120002903900310900121072001200541c0026a10b201220310b3012001200720032802046a20032802006b101520012000290390031091010240200128020c200141106a280200460440200141046a2107200128020021060c010b200141046a2107100020012802002106200128020c2001280210460d0010000b2008200420062007280200100c200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a10172202200041f0026a22012903001079101520022001290300107a200228020c200241106a28020047044010000b2002280204210420022802002108200541c0046a1017210120002802f802108e0121072001200541c0026a10b201220310b3012001200720032802046a20032802006b1015200120002802f802108c010240200128020c200141106a280200460440200141046a2107200128020021060c010b200141046a2107100020012802002106200128020c2001280210460d0010000b2008200420062007280200100c200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a10172202200041d8026a22012903001079101520022001290300107a200228020c200241106a28020047044010000b2002280204210420022802002108200541c0046a1017210120002f01e002108b0121072001200541c0026a10b201220310b3012001200720032802046a20032802006b1015200120002e01e002108c010240200128020c200141106a280200460440200141046a2107200128020021060c010b200141046a2107100020012802002106200128020c2001280210460d0010000b2008200420062007280200100c200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200041c0026a200041c8026a10b501200541c0066a1017220220004188026a22012903001079101520022001290300107a20004190026a2104200228020c200241106a28020047044010000b2002280204210820022802002107200541c0046a10172101200410880121062001200541c0026a10b201220310b3012001200620032802046a20032802006b1015200120041089010240200128020c200141106a280200460440200141046a2104200128020021060c010b200141046a2104100020012802002106200128020c2001280210460d0010000b2007200820062004280200100c200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a10172202200041c8016a22012903001079101520022001290300107a200041d0016a2104200228020c200241106a28020047044010000b2002280204210820022802002107200541c0046a10172101200410830121062001200541c0026a10b201220310b3012001200620032802046a20032802006b1015200120041084010240200128020c200141106a280200460440200141046a2104200128020021060c010b200141046a2104100020012802002106200128020c2001280210460d0010000b2007200820062004280200100c200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200041a8016a200041b0016a10b501200541c0066a1017220220004190016a22012903001079101520022001290300107a200228020c200241106a28020047044010000b2002280204210420022802002108200541c0046a1017210120002d009801107421072001200541c0026a10b201220310b3012001200720032802046a20032802006b1015200120002d00980110200240200128020c200141106a280200460440200141046a2107200128020021060c010b200141046a2107100020012802002106200128020c2001280210460d0010000b2008200420062007280200100c200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a10172201200041f0006a22022903001079101520012002290300107a200041f8006a2104200128020c200141106a28020047044010000b2001280204210820012802002107200541c0046a101721022004107d21062002200541c0026a10b201220310b3012002200620032802046a20032802006b101502402002200520041018101d220228020c200241106a280200460440200241046a2104200228020021060c010b200241046a2104100020022802002106200228020c2002280210460d0010000b2007200820062004280200100c200328020022040440200320043602040b200228020c22030440200220033602100b200128020c22020440200120023602100b200541c0066a10172202200041d0006a22012903001079101520022001290300107a200228020c200241106a28020047044010000b2002280204210420022802002108200541c0046a101721012000290358107921072001200541c0026a10b201220310b3012001200720032802046a20032802006b101520012000290358107a0240200128020c200141106a280200460440200141046a2107200128020021060c010b200141046a2107100020012802002106200128020c2001280210460d0010000b2008200420062007280200100c200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a10172202200041386a22012903001079101520022001290300107a200228020c200241106a28020047044010000b2002280204210420022802002108200541c0046a101721012000280240107821072001200541c0026a10b201220310b3012001200720032802046a20032802006b10152001200028024010200240200128020c200141106a280200460440200141046a2107200128020021060c010b200141046a2107100020012802002106200128020c2001280210460d0010000b2008200420062007280200100c200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a10172202200041206a22012903001079101520022001290300107a200228020c200241106a28020047044010000b2002280204210420022802002108200541c0046a1017210120002f0128107621072001200541c0026a10b201220310b3012001200720032802046a20032802006b1015200120002f012810200240200128020c200141106a280200460440200141046a2107200128020021060c010b200141046a2107100020012802002106200128020c2001280210460d0010000b2008200420062007280200100c200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a1017220220002903081079101520022000290308107a200228020c200241106a28020047044010000b2002280204210420022802002108200541c0046a1017210120002d0010107421072001200541c0026a10b201220310b3012001200720032802046a20032802006b1015200120002d001010200240200128020c200141106a280200460440200141046a2107200128020021060c010b200141046a2107100020012802002106200128020c2001280210460d0010000b2008200420062007280200100c200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0086a24000b2601017f02402000280204450d0020002802002d000041c001490d00200010b60121010b20010b800101037f230041106b22012400200010ae0102400240200010af01450d002000280204450d0020002802002d000041c001490d010b10000b200141086a200010b001200128020c220041024f044010000b200128020821020340200004402000417f6a210020022d00002103200241016a21020c010b0b200141106a240020030b5801027f230041206b22012400200141186a4100360200200141106a4200370300200141086a42003703002001420037030020012000ad42ff01834200105b210020012802002102200041046a101b200141206a240020020b8b0101037f230041106b22012400200010ae0102400240200010af01450d002000280204450d0020002802002d000041c001490d010b10000b200141086a200010b001200128020c220041034f044010000b200128020821030340200004402000417f6a210020032d00002002410874722102200341016a21030c010b0b200141106a2400200241ffff03710b5401017f230041206b22012400200141186a4100360200200141106a4200370300200141086a4200370300200142003703002001200041ffff0371101f200128020021002001410472101b200141206a240020000b860101037f230041106b22012400200010ae0102400240200010af01450d002000280204450d0020002802002d000041c001490d010b10000b200141086a200010b001200128020c220041054f044010000b200128020821030340200004402000417f6a210020032d00002002410874722102200341016a21030c010b0b200141106a240020020b4f01017f230041206b22012400200141186a4100360200200141106a4200370300200141086a42003703002001420037030020012000101f200128020021002001410472101b200141206a240020000b5001027f230041206b22012400200141186a4100360200200141106a4200370300200141086a4200370300200142003703002001200010b401200128020021022001410472101b200141206a240020020b0a00200020014200105e0b1a0020004200370200200041086a4100360200200010b70120000ba40201057f230041206b22022400024002402000280204044020002802002d000041c001490d010b200241086a107b1a0c010b200241186a200010b001200010b80121030240024002400240200228021822000440200228021c220520034f0d010b41002100200241106a410036020020024200370308410021050c010b200241106a4100360200200242003703082000200520032003417f461b22046a21052004410a4b0d010b200220044101743a0008200241086a41017221030c010b200441106a4170712206104021032002200436020c20022006410172360208200220033602100b03402000200546450440200320002d00003a0000200341016a2103200041016a21000c010b0b200341003a00000b2001200241086a10b901200241206a24000b5801027f230041306b22012400200141286a4100360200200141206a4200370300200141186a420037030020014200370310200141106a200120001018101a210020012802102102200041046a101b200141306a240020020b0e002001200010734100473a00000b4401027f230041f00b6b2202240020001072410247044010000b200220004101106c200210ba01210020021070210320022000200111000020031071200241f00b6a24000b7b01027f230041900c6b220224002000106f200241086a10702103200241086a20011101002100200241f80b6a10172201200010bb01101520012000108c01200128020c200141106a28020047044010000b20012802002001280204100e200128020c22000440200120003602100b20031071200241900c6a24000b180020004200370200200041086a41003602002000107b1a0b2801017f230041206b22022400200241086a20004100106c200241086a2001107c200241206a24000b5001017f230041206b22012400200141186a4100360200200141106a4200370300200141086a4200370300200142003703002001200010bc01200128020021002001410472101b200141206a240020000b6e01027f230041406a2202240020004101101c2100200241386a4100360200200241306a4200370300200241286a420037030020024200370320200241206a200241106a20011018101a21032000200228022010152000200220011018101d1a200341046a101b200241406b24000be10201027f02402001450d00200041003a0000200020016a2203417f6a41003a000020014103490d00200041003a0002200041003a00012003417d6a41003a00002003417e6a41003a000020014107490d00200041003a00032003417c6a41003a000020014109490d002000410020006b41037122026a220341003602002003200120026b417c7122026a2201417c6a410036020020024109490d002003410036020820034100360204200141786a4100360200200141746a410036020020024119490d002003410036021820034100360214200341003602102003410036020c200141706a41003602002001416c6a4100360200200141686a4100360200200141646a41003602002002200341047141187222026b2101200220036a2102034020014120490d0120024200370300200241186a4200370300200241106a4200370300200241086a4200370300200241206a2102200141606a21010c000b000b20000b19002000107b1a2000410c6a107b1a200041186a107b1a20000b5701017f230041206b22022400200241086a20004100106c200241086a2001108201200241086a20004101106c200241086a2001410c6a107c200241086a20004102106c200241086a200141186a107c200241206a24000b7a01027f230041406a22012400200141186a4100360200200141106a4200370300200141086a4200370300200142003703002001410010192202200010bc012002200141306a2000410c6a1018101a200141206a200041186a1018101a41011019210020012802002102200041046a101b200141406b240020020ba40101047f230041e0006b2202240020004103101c2100200241d8006a4100360200200241d0006a4200370300200241c8006a420037030020024200370340200241406b200110bc01200241406b200241306a2001410c6a22031018101a200241206a200141186a22041018101a2105200020022802401015200020011084012000200241106a20031018101d200220041018101d1a200541046a101b200241e0006a24000b3902017f017e230041106b220124002001200010bd0120012903002102200141106a2400420020024201837d200242018885a74110744110750b6202027f017e230041206b22012400200141186a4100360200200141106a4200370300200141086a42003703002001420037030020012000ad42308622034230872003423f8710be01210020012802002102200041046a101b200141206a240020020b1301017e20002001ac22022002423f8710bf010b3302017f017e230041106b220124002001200010bd0120012903002102200141106a2400420020024201837d200242018885a70b5201027f230041206b22012400200141186a4100360200200141106a4200370300200141086a4200370300200142003703002001200010c001210020012802002102200041046a101b200141206a240020020b4202017f027e230041106b220124002001200010bd01200141086a290300210320012903002102200141106a2400420020024201837d2003423f86200242018884850b5701037f230041206b22012400200141186a4100360200200141106a4200370300200141086a420037030020014200370300200120002000423f8710be01210220012802002103200241046a101b200141206a240020030b0e00200020012001423f8710bf010bb10201047f230041d0006b22022400024002402000280204450d0020002802002d000041c001490d002000107221032001280208200128020022046b4101752003490440200120022003200128020420046b410175200141086a10c101220310c201200310c3010b200241286a200010c401200241186a200010c501200141086a21050340200228022c200228021c46044020022802302002280220460d030b2002200241286a10c6012002107521030240200128020422002001280208490440200020033b01002001200041026a3602040c010b200241386a2001200020012802006b410175220041016a10552000200510c10121002002280240220420033b01002002200441026a3602402001200010c201200010c3010b200241286a10c7010c000b000b10000b200241d0006a24000b9c0101037f230041206b22012400200141186a4100360200200141106a4200370300200141086a420037030020014200370300024020002802002000280204460440200110c8010c010b200141001019210220002802042103200028020021000340200020034604402002410110191a05200220002f0100101f200041026a21000c010b0b0b200128020021002001410472101b200141206a240020000b4301017f2000200128020420012802006b410175101c21022001280204210020012802002101034020002001470440200220012f01001020200141026a21010c010b0b0be20201057f23004190016b22022400024002402000280204450d0020002802002d000041c001490d00200241c8006a200010c401200241386a200010c501200241146a21040340200228024c200228023c46044020022802502002280240460d030b200241206a200241c8006a10c601200241086a107b21002004107b2105200241206a10c901410247044010000b20024180016a107b2103200241e8006a200241206a4100106c200241e8006a2003107c2000200310b901200241d8006a107b2103200241e8006a200241206a4101106c200241e8006a2003107c2005200310b9012001200241e8006a2000104322062802004504404128104022032002290308370210200341186a200241106a280200360200200010b701200341246a200441086a2802003602002003411c6a2004290200370200200510b701200120022802682006200310450b200241c8006a10c7010c000b000b10000b20024190016a24000bd00101047f230041e0006b22012400200141206a4100360200200141186a4200370300200141106a42003703002001420037030802402000280208450440200141086a10c8010c010b200041046a2103200141086a410010192102200141346a2104200028020021000340200020034604402002410110191a05200141286a200041106a1051200241001019200141d0006a200141286a1018101a200141406b20041018101a410110191a2000103021000c010b0b0b20012802082100200141086a410472101b200141e0006a240020000b6101027f230041206b2202240020002001280208101c2103200141046a210020012802002101034020002001460440200241206a24000520034102101c200241106a200141106a1018101d20022001411c6a1018101d1a2001103021010c010b0b0bce0101037f230041206b22022400024002402000280204044020002802002d000041c001490d010b20024100360208200242003703000c010b200241186a200010b00120022802182103200241106a200010b00120022802102104200010b80121002002410036020820024200370300200020046a20036b2200450d0020022000104b20004101480d002002200228020420032000103c20006a3602040b2001280200044020014100360208200142003702000b2001200228020036020020012002290204370204200241206a24000b5301017f230041206b22022400200241186a4100360200200241106a4200370300200241086a4200370300200242003703002002200020011014210020022802002101200041046a101b200241206a240020010b2c01037f200041f8006a21022000210103402001107b21032001410c6a21012003410c6a2002470d000b20000b6101037f230041306b22022400200010c901410a47044010000b03402003410a460440200241306a240005200241206a107b2104200241086a20002003106c200241086a2004107c2001200410b9012001410c6a2101200341016a21030c010b0b0b800101037f230041306b22012400200141186a4100360200200141106a4200370300200141086a42003703002001420037030020014100101921030340200241f800464504402003200141206a200020026a1018101a1a2002410c6a21020c010b0b200341011019210220012802002103200241046a101b200141306a240020030b4401027f230041106b220224002000410a101c2103410021000340200041f800460440200241106a24000520032002200020016a1018101d1a2000410c6a21000c010b0b0b10002000107b1a2000410036020c20000b5d01027f230041306b22022400200010c901410247044010000b200241206a107b2103200241086a20004100106c200241086a2003107c2001200310b901200241086a20004101106c2001200241086a108d0136020c200241306a24000b7301027f230041406a22012400200141286a4100360200200141206a4200370300200141186a4200370300200142003703102001200010382100200141106a41001019200141306a20001018101a200028020c10c00141011019210020012802102102200041046a101b200141406b240020020b2a01017f230041106b2202240020004102101c200220011018101d200128020c108c01200241106a24000bd70101047f230041d0006b22022400024002402000280204450d0020002802002d000041c001490d00200241406b200010c401200241306a200010c501200241106a210403402002280244200228023446044020022802482002280238460d030b200241186a200241406b10c601200241186a200241086a107b2200107c2001200241cc006a200010432205280200450440411c104022032002290308370210200341186a2004280200360200200010b7012001200228024c2005200310450b200241406b10c7010c000b000b10000b200241d0006a24000b9e0101037f230041306b22012400200141186a4100360200200141106a4200370300200141086a42003703002001420037030002402000280208450440200110c8010c010b200041046a21032001410010192102200028020021000340200020034604402002410110191a052002200141206a200041106a1018101a1a2000103021000c010b0b0b200128020021002001410472101b200141306a240020000b4f01027f230041106b2202240020002001280208101c2103200141046a210020012802002101034020002001460440200241106a24000520032002200141106a1018101d1a2001103021010c010b0b0b9f0101027f23004190046b22022400200010ae0120024188046a200010b001200228028c042103024002402000280204450d0020034180024b0d0020002802002d000041c001490d010b10000b20024188026a4180021085011a200220034180022003418002491b22006b4188046a2002280288042000103c1a200241086a20024188026a418002103c1a2001200241086a418002103c1a20024190046a24000bc00101037f230041a0086b2201240020014198026a410036020020014190026a420037030020014188026a4200370300200142003703800220012000418002103c220041a0026a2000418002103c1a200041a0046a200041a0026a418002103c1a200041a0066a200041a0046a418002103c1a41012103024003402002418002460d01200041a0066a20026a2101200241016a210220012d0000450d000b41830221030b200020033602800220004180026a410472101b200041a0086a240020030bec0101037f230041d0006b22022400024002402000280204450d0020002802002d000041c001490d00200241406b200010c401200241306a200010c501200241106a210403402002280244200228023446044020022802482002280238460d030b200241186a200241406b10c601200241186a200241086a107b2203107c411410402200410036020020002002290308370208200041106a2004280200360200200310b70120002001360204200128020021032001200036020020002003360200200320003602042001200128020841016a360208200241406b10c7010c000b000b10000b200241d0006a24000b4d01037f02402000280208450d00200028020422012802002202200028020022032802043602042000410036020820032802042002360200034020002001460d01200128020421010c000b000b0b9d0101037f230041306b22012400200141186a4100360200200141106a4200370300200141086a42003703002001420037030002402000280208450440200110c8010c010b200041046a2102200141001019210303402002280200220220004604402003410110191a052003200141206a200241086a1018101a1a200241046a21020c010b0b0b200128020021022001410472101b200141306a240020020b4e01027f230041106b22032400200141046a210220002001280208101c21000340200228020022022001460440200341106a24000520002003200241086a1018101d1a200241046a21020c010b0b0bd10102037f027e230041406a22022400200010ae01200241386a200010b001200228023c2103024002402000280204450d00200341144b0d0020002802002d000041c001490d010b10000b200241306a22004100360200200241286a220442003703002002420037032020022003411420034114491b22036b41346a20022802382003103c1a200241186a20002802002200360200200241106a20042903002205370300200220022903202206370308200141106a2000360000200141086a200537000020012006370000200241406b24000b850202037f027e23004180016b22012400200141306a4100360200200141286a4200370300200141206a4200370300200141086a200041086a2900002204370300200141106a200041106a280000220236020020014200370318200120002900002205370300200141406b2004370300200141c8006a2002360200200141d8006a2004370300200141e0006a20023602002001200537033820012005370350200141f8006a2002360200200141f0006a200437030020012005370368410121020240034020034114460d01200141e8006a20036a2100200341016a210320002d0000450d000b411521020b20012002360218200141186a410472101b20014180016a240020020b750020004200370210200042ffffffff0f370208200020023602042000200136020002402003410871450d00200010cd0120024f0d002003410471044010000c010b200042003702000b02402003411071450d00200010cd0120024d0d0020034104710440100020000f0b200042003702000b20000b4101017f200028020445044010000b0240200028020022012d0000418101470d00200028020441014d047f100020002802000520010b2c00014100480d0010000b0b990101037f200028020445044041000f0b200010ae01200028020022022c0000220141004e044020014100470f0b027f4101200141807f460d001a200141ff0171220341b7014d0440200028020441014d047f100020002802000520020b2d00014100470f0b4100200341bf014b0d001a2000280204200141ff017141ca7e6a22014d047f100020002802000520020b20016a2d00004100470b0bd60101047f200110b8012204200128020422024b04401000200128020421020b200128020021052000027f02400240200204404100210120052c00002203417f4a0d01027f200341ff0171220141bf014d04404100200341ff017141b801490d011a200141c97e6a0c010b4100200341ff017141f801490d001a200141897e6a0b41016a21010c010b4101210120050d000c010b41002103200120046a20024b0d0020022001490d00410020022004490d011a200120056a2103200220016b20042004417f461b0c010b41000b360204200020033602000bc20101057f230041406a22022400200241286a101722032000290300107a200328020c200341106a28020047044010000b02402003280200220020032802042205100a22064504400c010b2002410036022020024200370318200241186a200610582000200520022802182200200228021c220520006b100b417f47044020012002200041016a20052000417f736a106b10ba013a0000200621040b2000450d002002200036021c0b200328020c22000440200320003602100b200241406b240020040b3000200041003602082000420037020020004101104b200028020441fe013a00002000200028020441016a36020420000b6101037f200028020c200041106a28020047044010000b200028020422022001280204200128020022036b22016a220420002802084b047f20002004105c20002802040520020b20002802006a20032001103c1a2000200028020420016a3602040b0b00200020014200105b1a0b8e0201067f230041406a22042400200441286a1017220220002903001079101520022000290300107a200228020c200241106a28020047044010000b2002280204210620022802002107200441106a1017210020012d000010bb0121052000200410b201220310b3012000200520032802046a20032802006b1015200020012c0000108c010240200028020c200041106a280200460440200041046a2101200028020021050c010b200041046a2101100020002802002105200028020c2000280210460d0010000b2007200620052001280200100c200328020022010440200320013602040b200028020c22030440200020033602100b200228020c22000440200220003602100b200441406b24000b820101047f230041106b2201240002402000280204450d0020002802002d000041c001490d00200141086a200010d101200128020c210003402000450d0120014100200128020822032003200010cf0122046a20034520002004497222031b3602084100200020046b20031b2100200241016a21020c000b000b200141106a240020020b2201017f03402001410c470440200020016a4100360200200141046a21010c010b0b0b800301037f200028020445044041000f0b200010ae0141012102024020002802002c00002201417f4a0d00200141ff0171220341b7014d0440200341807f6a0f0b02400240200141ff0171220141bf014d0440024020002802042201200341c97e6a22024d047f100020002802040520010b4102490d0020002802002d00010d0010000b200241054f044010000b20002802002d000145044010000b4100210241b7012101034020012003460440200241384f0d030c0405200028020020016a41ca7e6a2d00002002410874722102200141016a21010c010b000b000b200141f7014d0440200341c07e6a0f0b024020002802042201200341897e6a22024d047f100020002802040520010b4102490d0020002802002d00010d0010000b200241054f044010000b20002802002d000145044010000b4100210241f701210103402001200346044020024138490d0305200028020020016a418a7e6a2d00002002410874722102200141016a21010c010b0b0b200241ff7d490d010b10000b20020b5c00024020002d0000410171450440200041003b01000c010b200028020841003a00002000410036020420002d0000410171450d00200041003602000b20002001290200370200200041086a200141086a280200360200200110b7010b3902017f017e230041106b220124002001200010bd0120012903002102200141106a2400420020024201837d200242018885a74118744118750b6202027f017e230041206b22012400200141186a4100360200200141106a4200370300200141086a42003703002001420037030020012000ad42388622034238872003423f8710be01210020012802002102200041046a101b200141206a240020020b2701017f230041106b22022400200041001019200220011018101a410110191a200241106a24000ba10102027f027e230041106b22022400200110ae0102400240200110af01450d002001280204450d0020012802002d000041c001490d010b10000b200241086a200110b001200228020c220141114f044010000b20022802082103034020010440200542088620044238888421052001417f6a210120033100002004420886842104200341016a21030c010b0b2000200437030020002005370308200241106a24000b2301017e20002002423f87220320014201868520024201862001423f8884200385105b0b2301017e20002002423f87220320014201868520024201862001423f8884200385105e0b1301017e20002001ac22022002423f8710be010b4c01017f2000410036020c200041106a2003360200200104402001105321040b200020043602002000200420024101746a22023602082000200420014101746a36020c2000200236020420000b870101037f200120012802042000280204200028020022046b22036b2202360204200341004a0440200220042003103c1a200128020421020b200028020021032000200236020020012003360204200028020421022000200128020836020420012002360208200028020821022000200128020c3602082001200236020c200120012802043602000b2b01027f200028020821012000280204210203402001200247044020002001417e6a22013602080c010b0b0b0b0020002001410110ca010b0b0020002001410010ca010b170020002001280204200141086a280200411c10ad011a0bb70102057f017e230041106b22032400200041046a210102402000280200220204402001280200220504402005200041086a2802006a21040b20002004360204200041086a2002360200200341086a200141002004200210cf0110d00120002003290308220637020420004100200028020022012006422088a76b2202200220014b1b3602000c010b200020012802002201047f2001200041086a2802006a0541000b360204200041086a41003602000b200341106a24000b3901017f027f200041186a28020022010440200041086a280200200041146a2802002001105a0c010b20000b2201200128020041016a3602000b220002402000280204044020002802002d000041bf014b0d010b10000b200010b6010be70101037f230041106b2204240020004200370200200041086a410036020020012802042103024002402002450440200321020c010b410021022003450d002003210220012802002d000041c001490d00200441086a200110d10120004100200428020c220120042802082202200110cf0122032003417f461b20024520012003497222031b220536020820004100200220031b3602042000200120056b3602000c010b20012802002103200128020421012000410036020020004100200220016b20034520022001497222021b36020820004100200120036a20021b3602040b200441106a24000b3501017f230041106b220041908c0436020c41800c200028020c41076a417871220036020041840c200036020041880c3f003602000b100020020440200020012002103c1a0b0b3001017f200028020445044041000f0b4101210120002802002c0000417f4c047f200010ce01200010b8016a0520010b0b5b00027f027f41002000280204450d001a410020002802002c0000417f4a0d011a20002802002d0000220041bf014d04404100200041b801490d011a200041c97e6a0c010b4100200041f801490d001a200041897e6a0b41016a0b0b2901017f230041206b22022400200241086a20002001411410ad0110cd012100200241206a240020000b5b01027f2000027f0240200128020022054504400c010b200220036a200128020422014b0d0020012002490d00410020012003490d011a200220056a2104200120026b20032003417f461b0c010b41000b360204200020043602000b2401017f200110b801220220012802044b044010000b20002001200110ce01200210d0010b7b01037f0340024020002802102201200028020c460d00200141786a2802004504401000200028021021010b200141786a22022002280200417f6a220336020020030d002000200236021020002001417c6a2802002201200028020420016b220210026a10d301200120002802006a22012002200110030c010b0b0b3601017f200028020820014904402001106720002802002000280204103c210220002001360208200020023602000b200020013602040b0bfa0301004180080bf203746f70696331006461746131006a735f636f6e7472616374006576656e740073657455696e7433324576740073657455696e743136457674007472616e7366657200696e69740073657455696e74380067657455696e74380073657455696e7431360067657455696e7431360073657455696e7433320067657455696e7433320073657455696e7436340067657455696e74363400736574537472696e6700676574537472696e6700736574426f6f6c00676574426f6f6c00736574436861720067657443686172007365744d657373616765006765744d657373616765007365744d794d657373616765006765744d794d65737361676500736574496e743800676574496e743800736574496e74313600676574496e74313600736574496e74333200676574496e74333200736574496e74363400676574496e74363400736574566563746f7200676574566563746f72007365744d6170006765744d617000746573744d756c7469506172616d730073657442797465730067657442797465730073657441727261790067657441727261790073657450616972006765745061697200736574536574006765745365740073657446697865644861736800676574466978656448617368007365744c697374006765744c69737400736574416464726573730067657441646472657373' +cabi = [{"constant":false,"input":[{"name":"input","type":"string[10]"}],"name":"setArray","output":"void","type":"Action"},{"constant":false,"input":[{"name":"input","type":"FixedHash<256>"}],"name":"setFixedHash","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getFixedHash","output":"FixedHash<256>","type":"Action"},{"constant":true,"input":[],"name":"getChar","output":"int8","type":"Action"},{"baseclass":[],"fields":[{"name":"head","type":"string"}],"name":"message","type":"struct"},{"constant":false,"input":[{"name":"msg","type":"message"}],"name":"setMessage","output":"void","type":"Action"},{"constant":false,"input":[{"name":"input","type":"int32"}],"name":"setInt32","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getPair","output":"pair","type":"Action"},{"anonymous":false,"input":[{"name":"topic","type":"string"},{"name":"arg1","type":"string"}],"name":"transfer","topic":1,"type":"Event"},{"anonymous":false,"input":[{"name":"topic","type":"string"},{"name":"arg1","type":"string"},{"name":"arg2","type":"uint16"}],"name":"setUint16Evt","topic":1,"type":"Event"},{"constant":false,"input":[{"name":"addr","type":"FixedHash<20>"}],"name":"setAddress","output":"void","type":"Action"},{"anonymous":false,"input":[{"name":"topic1","type":"string"},{"name":"topic2","type":"uint32"},{"name":"arg1","type":"string"},{"name":"arg2","type":"uint32"},{"name":"arg3","type":"uint32"}],"name":"setUint32Evt","topic":2,"type":"Event"},{"constant":false,"input":[],"name":"init","output":"void","type":"Action"},{"constant":false,"input":[{"name":"input","type":"uint8"}],"name":"setUint8","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getUint8","output":"uint8","type":"Action"},{"constant":false,"input":[{"name":"input","type":"uint16"}],"name":"setUint16","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getUint16","output":"uint16","type":"Action"},{"constant":false,"input":[{"name":"input","type":"uint32"}],"name":"setUint32","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getUint32","output":"uint32","type":"Action"},{"constant":false,"input":[{"name":"input","type":"uint64"}],"name":"setUint64","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getUint64","output":"uint64","type":"Action"},{"constant":false,"input":[{"name":"input","type":"string"}],"name":"setString","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getString","output":"string","type":"Action"},{"constant":false,"input":[{"name":"input","type":"bool"}],"name":"setBool","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getBool","output":"bool","type":"Action"},{"constant":false,"input":[{"name":"input","type":"int8"}],"name":"setChar","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getMessage","output":"message","type":"Action"},{"baseclass":["message"],"fields":[{"name":"body","type":"string"},{"name":"end","type":"string"}],"name":"my_message","type":"struct"},{"constant":false,"input":[{"name":"msg","type":"my_message"}],"name":"setMyMessage","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getMyMessage","output":"my_message","type":"Action"},{"constant":false,"input":[{"name":"input","type":"int8"}],"name":"setInt8","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getInt8","output":"int8","type":"Action"},{"constant":false,"input":[{"name":"input","type":"int16"}],"name":"setInt16","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getInt16","output":"int16","type":"Action"},{"constant":true,"input":[],"name":"getInt32","output":"int32","type":"Action"},{"constant":false,"input":[{"name":"input","type":"int64"}],"name":"setInt64","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getInt64","output":"int64","type":"Action"},{"constant":false,"input":[{"name":"vec","type":"uint16[]"}],"name":"setVector","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getVector","output":"uint16[]","type":"Action"},{"constant":false,"input":[{"name":"input","type":"map"}],"name":"setMap","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getMap","output":"map","type":"Action"},{"constant":false,"input":[{"name":"msg","type":"message"},{"name":"input1","type":"int32"},{"name":"input2","type":"bool"}],"name":"testMultiParams","output":"void","type":"Action"},{"constant":false,"input":[{"name":"input","type":"uint8[]"}],"name":"setBytes","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getBytes","output":"uint8[]","type":"Action"},{"constant":true,"input":[],"name":"getArray","output":"string[10]","type":"Action"},{"constant":false,"input":[{"name":"input","type":"pair"}],"name":"setPair","output":"void","type":"Action"},{"constant":false,"input":[{"name":"input","type":"set"}],"name":"setSet","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getSet","output":"set","type":"Action"},{"constant":false,"input":[{"name":"input","type":"list"}],"name":"setList","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getList","output":"list","type":"Action"},{"constant":true,"input":[],"name":"getAddress","output":"FixedHash<20>","type":"Action"}] +msghash = '0x1476abb745d423bf09273f1afd887d951181d25adc66c4834a70491911b7f750' +vrs = ( + 0x1c, + 0xe6ca9bba58c88611fad66a6ce8f996908195593807c4b38bd528d2cff09d4eb3, + 0x3e5bfbbf4d3e39b1a2fd816a7680c19ebebaf3a141b239934ad43cb33fcec8ce) +signature = '0xe6ca9bba58c88611fad66a6ce8f996908195593807c4b38bd528d2cff09d4eb33e5bfbbf4d3e39b1a2fd816a7680c19ebebaf3a141b239934ad43cb33fcec8ce1c' +# Instantiate and deploy contract +# data=b'anything' +# hashdata=HexBytes(sm3.sm3_hash(func.bytes_to_list(data))) +payable = platon.wasmcontract(abi=cabi, bytecode=bytecode,vmtype=1) +# signhash=platon.account.signHash(hashdata,send_privatekey,'SM') +# verifysign=platon.account.sm_verify(signhash,hashdata,publickey) +# +# pubkey=platon.account.recoverHash(msghash, vrs=vrs) +# keystore=platon.account.encrypt(send_privatekey,'123456','SM') +# prikey=platon.account.decrypt(keystore,'123456','SM') +#密钥签名的交易 +txn = payable.constructor().buildTransaction({ + 'chainId':200, + 'from': from_address, + 'gas':2000000, + 'nonce':platon.getTransactionCount(from_address), + } +) +def SendTxn(txn): + signed_txn = platon.account.signTransaction(txn, private_key=send_privatekey, net_type=DEFAULTHRP, mode='SM') #,mode='SM' + res = platon.sendRawTransaction(signed_txn.rawTransaction).hex() + txn_receipt = platon.waitForTransactionReceipt(res) + print(res) + return txn_receipt +tx_receipt=SendTxn(txn) +print(tx_receipt) \ No newline at end of file diff --git a/tests/test_basic.py b/tests/test_basic.py new file mode 100644 index 0000000..08ebb21 --- /dev/null +++ b/tests/test_basic.py @@ -0,0 +1,140 @@ +import json + +import allure +import pytest +from hexbytes import HexBytes +from client_sdk_python import Web3 + +from common import log +from common.abspath import abspath +from common.handle_param import handle, handle_param +from common.load_file import get_node_list +from conf import setting as conf +from data import basic as config_data +from utils.platon_lib import contract +from utils.platon_lib.contract import (PlatonContractTransaction, + contract_call_result_decode) +from utils.platon_lib.contract import encoder +from utils.platon_lib.event import Event +from utils.platon_lib.send_raw_transaction import send_raw_transaction + +collusion_list, _ = get_node_list(conf.NODE_YML) +node_url = collusion_list[0]['url'] +address = Web3.toChecksumAddress( + '493301712671ada506ba6ca7891f436d29185821') + +send_address = Web3.toChecksumAddress("0xdB245C0ebbCa84395c98c3b2607863cA36ABBD79") +send_privatekey = "b735b2d48e5f6e1dc897081f8655fdbb376ece5b2b648c55eee72c38102a0357" + + +def contract_deploy(pt, wasm_path, abi_path): + ''' + 部署wasm合约方法 + ''' + address = pt.eth.coinbase + pt.personal.unlockAccount(address, '88888888', 999999) + deploy_trans_hash = pt.contract_deploy(contract.get_byte_code(wasm_path), + contract.get_abi_bytes(abi_path), address) + try: + result = pt.eth.waitForTransactionReceipt(deploy_trans_hash) + except: + assert False, "等待超时,交易哈希:{}".format(deploy_trans_hash) + contract_address = result['contractAddress'] + log.info("合约地址:{}".format(contract_address)) + assert len(pt.eth.getCode(contract_address) + ) > 3, '合约部署异常,getCode(contract_address)结果异常' + return contract_address + + +def setup_module(): + pt_multi = PlatonContractTransaction(node_url) + for k, w in config_data.wasm.items(): + contract_address = contract_deploy(pt_multi, abspath(w), + abspath(config_data.abi[k])) + config_data.contract_address[k] = contract_address + handle(config_data.contract_address) + send_data = { + "to": send_address, + "from": address, + "gas": '9000', + "gasPrice": '1000000000', + "value": Web3.toWei(200, 'ether'), + } + tx_hash = pt_multi.eth.sendTransaction(send_data) + pt_multi.eth.waitForTransactionReceipt(tx_hash) + + +def teardown_module(): + log.info("结束了") + + +@allure.title("测试basic合约,方法{casedata[func]},name:{casedata[name]}") +@pytest.mark.parametrize('casedata', config_data.func["basic"]) +def test_contract(casedata): + """ + 用例主要测试基础数据类型,方法{},name:{} + """.format(casedata["func"], casedata["name"]) + log.info("方法{},name:{}".format(casedata["func"], casedata["name"])) + pt_multi = PlatonContractTransaction(node_url) + encode_param = handle_param(casedata["param"]) + data_list = [encoder.encode_type( + 2), encoder.encode_string(casedata["func"])] + encode_param + trans_hex = send_raw_transaction(send_address, send_privatekey, casedata["contract_address"], pt_multi.w3, 0, + data_list) + # trans_hex = pt_multi.contract_transaction( + # address, casedata["contract_address"], data_list) + try: + result = pt_multi.eth.waitForTransactionReceipt(trans_hex) + except: + assert False, "等待超时,交易哈希:{}".format(trans_hex) + log.info("transaction hex:{}".format(trans_hex)) + if casedata.get("event"): + event_data = ex_event(result, casedata) + log.info(event_data) + assert casedata["event"] in event_data['notify'][1], '合约交易失败,event事件无{}'.format( + casedata["event"]) + if casedata.get("notevent"): + a = 0 + try: + event_data = ex_event(result, casedata) + log.info("event data:{}".format(event_data)) + call_value = call(casedata, pt_multi) + log.info("call:{}".format(call_value)) + a = 1 + except: + log.info("没有event") + finally: + assert a == 0, "有执行event" + if casedata.get("expect"): + get_value = call(casedata, pt_multi) + log.info("call value:{}".format(get_value)) + assert get_value == casedata["expect"], 'get结果异常,预期值:{},实际结果:{}'.format( + casedata["expect_value"], get_value) + + +def call(casedata, pt_multi): + data_list_for_call = [encoder.encode_type( + 2), encoder.encode_string(casedata["call_func"])] + receive = pt_multi.contract_call( + address, casedata["contract_address"], data_list_for_call) + if casedata.get("expect_type") == "str": + value = contract_call_string(receive) + else: + value = contract_call_result_decode(receive) + return value + + +def ex_event(result, casedata): + topics = result['logs'][0]['topics'] + d = result['logs'][0]['data'] + event = Event( + json.load(open(abspath(config_data.abi[casedata["contract_name"]])))) + event_data = event.event_data(topics, d) + return event_data + + +def contract_call_string(call_result): + length = int(call_result[66:130], 16) * 2 + data = call_result[130:130 + length] + ret = HexBytes(data).decode() + return ret.lower() diff --git a/tests/test_contract.py b/tests/test_contract.py new file mode 100644 index 0000000..a380acb --- /dev/null +++ b/tests/test_contract.py @@ -0,0 +1,279 @@ +# -*- coding: UTF-8 -*- +""" +@author: DouYueWei +@time: 2018/11/30 14:08 +@usage: +""" +import json +import os +import time + +import allure +import pytest +from hexbytes import HexBytes +from client_sdk_python import Web3 + +from common import log +from common.abspath import abspath +from conf import setting as conf +from common.load_file import get_node_list +from utils.platon_lib import encoder +from utils.platon_lib.event import Event +from utils.platon_lib.contract import (PlatonContractTransaction, + contract_call_result_decode,get_byte_code,get_abi_bytes) + + +def contract_deploy(pt, wasm_path, abi_path): + ''' + 部署wasm合约方法 + ''' + address = pt.eth.coinbase + pt.personal.unlockAccount(address, '88888888', 999999) + deploy_trans_hash = pt.contract_deploy(get_byte_code(wasm_path), + get_abi_bytes(abi_path), address) + try: + result = pt.eth.waitForTransactionReceipt(deploy_trans_hash) + except: + assert False, "等待超时,交易哈希:{}".format(deploy_trans_hash) + contract_address = result['contractAddress'] + log.info("合约地址:{}".format(contract_address)) + assert len(pt.eth.getCode(contract_address) + ) > 3, '合约部署异常,getCode(contract_address)结果异常' + return contract_address + + +class TestContract: + node_yml = conf.NODE_YML + collusion_list, nocollusion_list = get_node_list(node_yml) + nocollusion_url = nocollusion_list[0]['url'] + collusion_url = collusion_list[0]['url'] + address = Web3.toChecksumAddress(conf.ADDRESS) + private_key_hex = conf.PRIVATE_KEY + private_key = HexBytes(private_key_hex) + url_list = [nocollusion_url, collusion_url] + param_list = [(abspath('./data/contract/Fibonacci.wasm'), + abspath('./data/contract/Fibonacci.cpp.abi.json'), 10, 143), + (abspath('./data/contract/matmul.wasm'), + abspath('./data/contract/matmul.cpp.abi.json'), 10, -183325)] + + @allure.title("非共识节点&共识节点 部署wasm合约测试") + @pytest.mark.parametrize('pt1', url_list) + def test_consensus_and_deconsensus_contract_deploy(self, pt1): + ''' + 非共识节点&共识节点 部署wasm合约测试 + ''' + pt = PlatonContractTransaction(pt1) + wasm_path = abspath('./data/contract/sum.wasm') + abi_path = abspath('./data/contract/sum.cpp.abi.json') + + # 部署合约 + contract_address = contract_deploy(pt, wasm_path, abi_path) + assert contract_address is not None, '合约部署失败,合约地址为空' + contract_code = pt.eth.getCode(contract_address) + assert len(contract_code) > 3, '合约部署异常,getCode(contract_address)结果异常' + + @allure.title("非共识节点&共识节点 wasm合约交易、event事件、call方法测试") + @pytest.mark.parametrize('pt1', url_list) + def test_consensus_and_deconsensus_contract_transaction(self, pt1): + ''' + 非共识节点&共识节点 wasm合约交易、event事件、call方法测试 + ''' + pt = PlatonContractTransaction(pt1) + wasm_path = abspath('./data/contract/sum.wasm') + abi_path = abspath('./data/contract/sum.cpp.abi.json') + address = pt.eth.coinbase + contract_address = contract_deploy(pt, wasm_path, abi_path) + + # 发送合约交易 + data_list = [encoder.encode_type( + 2), encoder.encode_string('set')] + trans_hex = pt.contract_transaction( + address, contract_address, data_list) + try: + result = pt.eth.waitForTransactionReceipt(trans_hex) + except: + assert False, "等待超时,交易哈希:{}".format(trans_hex) + # 解析event事件 + topics = result['logs'][0]['topics'] + data = result['logs'][0]['data'] + event = Event(json.load(open(abi_path))) + event_data = event.event_data(topics, data) + assert 'set success' in event_data['create'][0], '合约交易失败,event事件无"set success"' + # call方法查询交易结果 + data_list_for_call = [encoder.encode_type( + 2), encoder.encode_string('get')] + receive = pt.contract_call( + address, contract_address, data_list_for_call) + decoded_sum_result = int.from_bytes(receive, 'big') + assert decoded_sum_result == 1, '自增失败,预期自增后结果为1,实际值为{}'.format( + decoded_sum_result) + + @allure.title("非共识节点&共识节点 wasm合约输入、输出结果校验") + @pytest.mark.parametrize('pt1', url_list) + def test_consensus_and_deconsensus_contract_set_and_get_function(self, pt1): + ''' + 非共识节点&共识节点 wasm合约输入、输出结果校验 + ''' + pt = PlatonContractTransaction(pt1) + wasm_path = abspath('./data/contract/inputtest.wasm') + abi_path = abspath( + './data/contract/inputtest.cpp.abi.json') + address = pt.eth.coinbase + contract_address = contract_deploy(pt, wasm_path, abi_path) + set_value = -100 + + # 合约set方法存入int型数值 + data_list = [encoder.encode_type(2), encoder.encode_string('set'), + encoder.encode_int('int64', set_value)] + trans_hex = pt.contract_transaction( + address, contract_address, data_list) + try: + result = pt.eth.waitForTransactionReceipt(trans_hex) + except: + assert False, "等待超时,交易哈希:{}".format(trans_hex) + # 合约get方法获取存入的数值校验是否一致 + data_list_for_call = [encoder.encode_type( + 2), encoder.encode_string('get')] + receive = pt.contract_call( + address, contract_address, data_list_for_call) + get_value = contract_call_result_decode(receive) + assert get_value == set_value, 'get结果异常,预期值:{},实际结果:{}'.format( + set_value, get_value) + + def _singed_contract_deploy(self, pt, wasm_path, abi_path): + ''' + 部署wasm签名合约方法 + ''' + deploy_trans_hash = pt.signed_contract_deploy(get_byte_code(wasm_path), + get_abi_bytes( + abi_path), + self.address, self.private_key) + try: + result = pt.eth.waitForTransactionReceipt(deploy_trans_hash) + except: + assert False, "等待超时,交易哈希:{}".format(deploy_trans_hash) + contract_address = result['contractAddress'] + assert len(pt.eth.getCode(contract_address) + ) > 3, '合约部署异常,getCode(contract_address)结果异常' + return contract_address + + @allure.title("非共识节点&共识节点 部署wasm签名合约测试") + @pytest.mark.parametrize('pt1', url_list) + def test_consensus_and_deconsensus_singed_contract_deploy(self, pt1): + ''' + 非共识节点&共识节点 部署wasm签名合约测试 + ''' + pt = PlatonContractTransaction(pt1) + wasm_path = abspath('./data/contract/sum.wasm') + abi_path = abspath('./data/contract/sum.cpp.abi.json') + + # 部署合约 + contract_address = self._singed_contract_deploy( + pt, wasm_path, abi_path) + assert contract_address is not None, '合约部署失败,合约地址为空' + contract_code = pt.eth.getCode(contract_address) + assert len(contract_code) > 3, '合约部署异常,getCode(contract_address)结果异常' + + @allure.title("非共识节点&共识节点 wasm合约签名交易、event事件、call方法测试") + @pytest.mark.parametrize('pt1', url_list) + def test_consensus_and_deconsensus_singed_contract_transaction(self, pt1): + ''' + 非共识节点&共识节点 wasm合约签名交易、event事件、call方法测试 + ''' + pt = PlatonContractTransaction(pt1) + wasm_path = abspath('./data/contract/sum.wasm') + abi_path = abspath('./data/contract/sum.cpp.abi.json') + address = pt.eth.coinbase + contract_address = self._singed_contract_deploy( + pt, wasm_path, abi_path) + + # 发送合约交易 + data_list = [encoder.encode_type( + 2), encoder.encode_string('set')] + trans_hex = pt.signed_contract_transaction( + address, contract_address, data_list, self.private_key) + try: + result = pt.eth.waitForTransactionReceipt(trans_hex) + except: + assert False, "等待超时,交易哈希:{}".format(trans_hex) + # 解析event事件 + topics = result['logs'][0]['topics'] + data = result['logs'][0]['data'] + event = Event(json.load(open(abi_path))) + event_data = event.event_data(topics, data) + assert 'set success' in event_data['create'][0], '合约交易失败,event事件无"set success"' + # call方法查询交易结果 + data_list_for_call = [encoder.encode_type( + 2), encoder.encode_string('get')] + receive = pt.contract_call( + address, contract_address, data_list_for_call) + decoded_sum_result = int.from_bytes(receive, 'big') + assert decoded_sum_result == 1, '自增失败,预期自增后结果为1,实际值为{}'.format( + decoded_sum_result) + + @allure.title("非共识节点&共识节点 wasm签名合约输入、输出结果校验") + @pytest.mark.parametrize('pt1', url_list) + def test_consensus_and_deconsensus_signed_contract_set_and_get_function(self, pt1): + ''' + 非共识节点&共识节点 wasm签名合约输入、输出结果校验 + ''' + pt = PlatonContractTransaction(pt1) + wasm_path = abspath('./data/contract/inputtest.wasm') + abi_path = abspath( + './data/contract/inputtest.cpp.abi.json') + address = pt.eth.coinbase + contract_address = self._singed_contract_deploy( + pt, wasm_path, abi_path) + set_value = -100 + + # 合约set方法存入int型数值 + data_list = [encoder.encode_type(2), encoder.encode_string('set'), + encoder.encode_int('int64', set_value)] + trans_hex = pt.signed_contract_transaction( + address, contract_address, data_list, self.private_key) + result = '' + for i in range(3): + try: + result = pt.eth.waitForTransactionReceipt(trans_hex) + except: + pt.reconnect() + assert result != '', "等待超时,交易哈希:{}".format(trans_hex) + + # 合约get方法获取存入的数值校验是否一致 + data_list_for_call = [encoder.encode_type( + 2), encoder.encode_string('get')] + receive = pt.contract_call( + address, contract_address, data_list_for_call) + get_value = contract_call_result_decode(receive) + assert get_value == set_value, 'get结果异常,预期值:{},实际结果:{}'.format( + set_value, get_value) + time.sleep(1) + + @allure.title("各算法合约计算结果测试") + @pytest.mark.parametrize('wasm_path,abi_path,set_value,expect_value', param_list) + def test_calc_contracts(self, wasm_path, abi_path, set_value, expect_value): + ''' + 各算法合约计算结果测试 + ''' + pt_one = PlatonContractTransaction(self.nocollusion_url) + address = pt_one.eth.coinbase + contract_address = contract_deploy( + pt_one, wasm_path, abi_path) + + # 合约set方法存入int型数值 + data_list = [encoder.encode_type(2), encoder.encode_string('set'), + encoder.encode_int('int64', set_value)] + trans_hex = pt_one.contract_transaction( + address, contract_address, data_list) + try: + result = pt_one.eth.waitForTransactionReceipt(trans_hex) + except: + assert False, "等待超时,交易哈希:{}".format(trans_hex) + # 合约get方法获取存入的数值校验是否一致 + data_list_for_call = [encoder.encode_type( + 2), encoder.encode_string('get')] + receive = pt_one.contract_call( + address, contract_address, data_list_for_call) + get_value = contract_call_result_decode(receive) + assert get_value == expect_value, 'get结果异常,预期值:{},实际结果:{}'.format( + expect_value, get_value) diff --git a/tests/test_sdk1.py b/tests/test_sdk1.py new file mode 100644 index 0000000..29e3607 --- /dev/null +++ b/tests/test_sdk1.py @@ -0,0 +1,26 @@ +from client_sdk_python import Web3, HTTPProvider +from client_sdk_python.eth import PlatON +from hexbytes import HexBytes + +# get blockNumber +w3 = Web3(HTTPProvider("http://localhost:6789")) +platon = PlatON(w3) +block_number = platon.blockNumber +print(block_number) + +# get Balance +address = '0x493301712671Ada506ba6Ca7891F436D29185821' +balance = platon.getBalance(address) +print(balance) + +# sendtransaction +to = '0xC1f330B214668beAc2E6418Dd651B09C759a4Bf5' +w3.personal.unlockAccount(address, "password", 60) +data = { + "from": address, + "to": to, + "value": 0x10909, +} +transaction_hex = HexBytes(platon.sendTransaction(data)).hex() +result = platon.waitForTransactionReceipt(transaction_hex) +print(result) \ No newline at end of file diff --git a/tests/wasm/example1/main.abi.json b/tests/wasm/example1/main.abi.json new file mode 100644 index 0000000..adfd1d0 --- /dev/null +++ b/tests/wasm/example1/main.abi.json @@ -0,0 +1,62 @@ +[ + { + "anonymous": false, + "input": [ + { + "name": "topic1", + "type": "string" + }, + { + "name": "topic2", + "type": "int32" + } + ], + "name": "Add", + "topic": 2, + "type": "Event" + }, + { + "constant": false, + "input": [], + "name": "init", + "output": "void", + "type": "Action" + }, + { + "constant": false, + "input": [], + "name": "makeNumber", + "output": "void", + "type": "Action" + }, + { + "constant": false, + "input": [], + "name": "deleteNumber", + "output": "void", + "type": "Action" + }, + { + "constant": true, + "input": [], + "name": "get_Numbers", + "output": "list", + "type": "Action" + }, + { + "constant": false, + "input": [ + { + "name": "a", + "type": "int32" + }, + { + "name": "b", + "type": "int32" + } + ], + "name": "calcAdd", + "output": "int32", + "type": "Action" + } +] \ No newline at end of file diff --git a/tests/wasm/example1/main.cpp b/tests/wasm/example1/main.cpp new file mode 100644 index 0000000..9a898d8 --- /dev/null +++ b/tests/wasm/example1/main.cpp @@ -0,0 +1,46 @@ +#include + +#include + +CONTRACT Simple: public platon::Contract +{ +private: + platon::StorageType<"mylist"_n, std::list> info; + platon::StorageType<"myNumber"_n, int> cur; + + PLATON_EVENT2(Add, std::string , int); + +public: + ACTION void init() + { + cur.self() = 1; + } + + ACTION void makeNumber() + { + info.self().push_back(++cur.self()); + } + + ACTION void deleteNumber() + { + info.self().pop_front(); + } + + CONST std::list get_Numbers() + { + return info.self(); + } + + ACTION int calcAdd(int a, int b) + { + //auto sender = platon::platon_caller(); + //std::list lv; + //lv.push_back(a+b); + auto c = a + b; + PLATON_EMIT_EVENT1(Add, "calcAdd", c); + + return c; + } +}; + +PLATON_DISPATCH(Simple, (init)(makeNumber)(deleteNumber)(get_Numbers)(calcAdd)) diff --git a/tests/wasm/example1/main.wasm b/tests/wasm/example1/main.wasm new file mode 100644 index 0000000..cb9bc80 Binary files /dev/null and b/tests/wasm/example1/main.wasm differ diff --git a/tests/wasm/example2/main.abi.json b/tests/wasm/example2/main.abi.json new file mode 100644 index 0000000..578409a --- /dev/null +++ b/tests/wasm/example2/main.abi.json @@ -0,0 +1,145 @@ +[ + { + "constant": false, + "input": [ + { + "name": "ele", + "type": "int32" + } + ], + "name": "putElement", + "output": "void", + "type": "Action" + }, + { + "constant": true, + "input": [], + "name": "makeCall", + "output": "int32", + "type": "Action" + }, + { + "constant": false, + "input": [], + "name": "clearElement", + "output": "void", + "type": "Action" + }, + { + "anonymous": false, + "input": [ + { + "name": "topic", + "type": "string" + }, + { + "name": "arg1", + "type": "uint32" + } + ], + "name": "Add", + "topic": 1, + "type": "Event" + }, + { + "anonymous": false, + "input": [ + { + "name": "topic", + "type": "string" + }, + { + "name": "arg1", + "type": "int32" + } + ], + "name": "call2", + "topic": 1, + "type": "Event" + }, + { + "anonymous": false, + "input": [ + { + "name": "topic", + "type": "string" + }, + { + "name": "arg1", + "type": "int32" + } + ], + "name": "put", + "topic": 1, + "type": "Event" + }, + { + "anonymous": false, + "input": [ + { + "name": "topic", + "type": "string" + }, + { + "name": "arg1", + "type": "uint32" + } + ], + "name": "clear", + "topic": 1, + "type": "Event" + }, + { + "baseclass": [], + "fields": [ + { + "name": "myParams", + "type": "int32[]" + } + ], + "name": "inputParams", + "type": "struct" + }, + { + "constant": false, + "input": [ + { + "name": "ipa", + "type": "inputParams" + } + ], + "name": "init", + "output": "void", + "type": "Action" + }, + { + "constant": true, + "input": [], + "name": "getParams", + "output": "int32[]", + "type": "Action" + }, + { + "constant": false, + "input": [], + "name": "AddCalc", + "output": "int32", + "type": "Action" + }, + { + "constant": true, + "input": [ + { + "name": "a", + "type": "int32" + }, + { + "name": "b", + "type": "int32" + } + ], + "name": "makeCall2", + "output": "int32", + "type": "Action" + } +] \ No newline at end of file diff --git a/tests/wasm/example2/main.cpp b/tests/wasm/example2/main.cpp new file mode 100644 index 0000000..299ce40 --- /dev/null +++ b/tests/wasm/example2/main.cpp @@ -0,0 +1,83 @@ +#include + +#include +#include + +using namespace std; + +class inputParams +{ +public: + inputParams(){} + inputParams(std::vector vParams) + { + myParams = vParams; + } + +public: + std::vector myParams; + PLATON_SERIALIZE(inputParams, (myParams)) +}; + + +CONTRACT simpleOps: public platon::Contract{ +public: + PLATON_EVENT1(Add, std::string, uint32_t) + PLATON_EVENT1(call2, std::string, int) + PLATON_EVENT1(put, std::string, int) + PLATON_EVENT1(clear, std::string, uint32_t) + + ACTION void init(const inputParams& ipa){ + iParams.self() = ipa; + } + + CONST std::vector getParams(){ + return iParams.self().myParams; + } + + CONST int makeCall(){ + std::vector params = iParams.self().myParams; + int rst = 0; + for (auto itr = params.begin(); itr != params.end(); ++itr) + { + rst += *itr; + } + return rst; + } + + ACTION void putElement(int ele){ + iParams.self().myParams.push_back(ele); + PLATON_EMIT_EVENT1(put, "putElement" , ele); + } + + ACTION void clearElement(){ + if (!iParams.self().myParams.empty()) + { + iParams.self().myParams.clear(); + } + uint32_t returnValue = 73; + PLATON_EMIT_EVENT1(clear, "clearElement" , returnValue); + } + + ACTION int AddCalc(){ + int rst = 0; + for (auto itr = iParams.self().myParams.begin(); itr != iParams.self().myParams.end(); ++itr) + { + rst += *itr; + } + + PLATON_EMIT_EVENT1(Add, "AddCalc", rst); + return rst; + } + + CONST int makeCall2(int a, int b){ + int c = a + b; + PLATON_EMIT_EVENT1(call2, "makeCall2", c); + return c; + } + +private: + platon::StorageType<"Params"_n, inputParams> iParams; +}; + +PLATON_DISPATCH(simpleOps, (init)(getParams)(makeCall)(putElement)(clearElement)(AddCalc)(makeCall2)) diff --git a/tests/wasm/example2/main.wasm b/tests/wasm/example2/main.wasm new file mode 100644 index 0000000..b4cd058 Binary files /dev/null and b/tests/wasm/example2/main.wasm differ diff --git a/tests/wasm/example3/main.abi.json b/tests/wasm/example3/main.abi.json new file mode 100644 index 0000000..2089f14 --- /dev/null +++ b/tests/wasm/example3/main.abi.json @@ -0,0 +1,577 @@ +[ + { + "constant": true, + "input": [], + "name": "getVector", + "output": "uint16[]", + "type": "Action" + }, + { + "constant": false, + "input": [ + { + "name": "input", + "type": "int8" + } + ], + "name": "setChar", + "output": "void", + "type": "Action" + }, + { + "constant": false, + "input": [ + { + "name": "input", + "type": "int8" + } + ], + "name": "setInt8", + "output": "void", + "type": "Action" + }, + { + "constant": false, + "input": [ + { + "name": "input", + "type": "uint8" + } + ], + "name": "setUint8", + "output": "void", + "type": "Action" + }, + { + "constant": true, + "input": [], + "name": "getPair", + "output": "pair", + "type": "Action" + }, + { + "baseclass": [], + "fields": [ + { + "name": "head", + "type": "string" + } + ], + "name": "message", + "type": "struct" + }, + { + "baseclass": [ + "message" + ], + "fields": [ + { + "name": "body", + "type": "string" + }, + { + "name": "end", + "type": "string" + } + ], + "name": "my_message", + "type": "struct" + }, + { + "constant": true, + "input": [], + "name": "getMyMessage", + "output": "my_message", + "type": "Action" + }, + { + "anonymous": false, + "input": [ + { + "name": "topic", + "type": "string" + }, + { + "name": "arg1", + "type": "string" + } + ], + "name": "transfer", + "topic": 1, + "type": "Event" + }, + { + "anonymous": false, + "input": [ + { + "name": "topic", + "type": "string" + }, + { + "name": "arg2", + "type": "string" + }, + { + "name": "arg1", + "type": "uint16" + } + ], + "name": "setUint16Evt", + "topic": 1, + "type": "Event" + }, + { + "constant": false, + "input": [ + { + "name": "input", + "type": "FixedHash<256>" + } + ], + "name": "setFixedHash", + "output": "void", + "type": "Action" + }, + { + "anonymous": false, + "input": [ + { + "name": "topic1", + "type": "string" + }, + { + "name": "topic2", + "type": "uint32" + }, + { + "name": "arg3", + "type": "string" + }, + { + "name": "arg2", + "type": "uint32" + }, + { + "name": "arg1", + "type": "uint32" + } + ], + "name": "setUint32Evt", + "topic": 2, + "type": "Event" + }, + { + "constant": false, + "input": [], + "name": "init", + "output": "void", + "type": "Action" + }, + { + "constant": true, + "input": [], + "name": "getUint8", + "output": "uint8", + "type": "Action" + }, + { + "constant": false, + "input": [ + { + "name": "input", + "type": "uint16" + } + ], + "name": "setUint16", + "output": "void", + "type": "Action" + }, + { + "constant": true, + "input": [], + "name": "getUint16", + "output": "uint16", + "type": "Action" + }, + { + "constant": false, + "input": [ + { + "name": "input", + "type": "uint32" + } + ], + "name": "setUint32", + "output": "void", + "type": "Action" + }, + { + "constant": true, + "input": [], + "name": "getUint32", + "output": "uint32", + "type": "Action" + }, + { + "constant": false, + "input": [ + { + "name": "input", + "type": "uint64" + } + ], + "name": "setUint64", + "output": "void", + "type": "Action" + }, + { + "constant": true, + "input": [], + "name": "getUint64", + "output": "uint64", + "type": "Action" + }, + { + "constant": false, + "input": [ + { + "name": "input", + "type": "string" + } + ], + "name": "setString", + "output": "void", + "type": "Action" + }, + { + "constant": true, + "input": [], + "name": "getString", + "output": "string", + "type": "Action" + }, + { + "constant": false, + "input": [ + { + "name": "input", + "type": "bool" + } + ], + "name": "setBool", + "output": "void", + "type": "Action" + }, + { + "constant": true, + "input": [], + "name": "getBool", + "output": "bool", + "type": "Action" + }, + { + "constant": true, + "input": [], + "name": "getChar", + "output": "int8", + "type": "Action" + }, + { + "constant": false, + "input": [ + { + "name": "msg", + "type": "message" + } + ], + "name": "setMessage", + "output": "void", + "type": "Action" + }, + { + "constant": true, + "input": [], + "name": "getMessage", + "output": "message", + "type": "Action" + }, + { + "constant": false, + "input": [ + { + "name": "msg", + "type": "my_message" + } + ], + "name": "setMyMessage", + "output": "void", + "type": "Action" + }, + { + "constant": true, + "input": [], + "name": "getInt8", + "output": "int8", + "type": "Action" + }, + { + "constant": false, + "input": [ + { + "name": "input", + "type": "int16" + } + ], + "name": "setInt16", + "output": "void", + "type": "Action" + }, + { + "constant": true, + "input": [], + "name": "getInt16", + "output": "int16", + "type": "Action" + }, + { + "constant": false, + "input": [ + { + "name": "input", + "type": "int32" + } + ], + "name": "setInt32", + "output": "void", + "type": "Action" + }, + { + "constant": true, + "input": [], + "name": "getInt32", + "output": "int32", + "type": "Action" + }, + { + "constant": false, + "input": [ + { + "name": "input", + "type": "int64" + } + ], + "name": "setInt64", + "output": "void", + "type": "Action" + }, + { + "constant": true, + "input": [], + "name": "getInt64", + "output": "int64", + "type": "Action" + }, + { + "constant": false, + "input": [ + { + "name": "input", + "type": "float" + } + ], + "name": "setFloat", + "output": "void", + "type": "Action" + }, + { + "constant": true, + "input": [], + "name": "getFloat", + "output": "float", + "type": "Action" + }, + { + "constant": false, + "input": [ + { + "name": "input", + "type": "double" + } + ], + "name": "setDouble", + "output": "void", + "type": "Action" + }, + { + "constant": true, + "input": [], + "name": "getDouble", + "output": "double", + "type": "Action" + }, + { + "constant": false, + "input": [ + { + "name": "vec", + "type": "uint16[]" + } + ], + "name": "setVector", + "output": "void", + "type": "Action" + }, + { + "constant": false, + "input": [ + { + "name": "input", + "type": "map" + } + ], + "name": "setMap", + "output": "void", + "type": "Action" + }, + { + "constant": true, + "input": [], + "name": "getMap", + "output": "map", + "type": "Action" + }, + { + "constant": false, + "input": [ + { + "name": "msg", + "type": "message" + }, + { + "name": "input1", + "type": "int32" + }, + { + "name": "input2", + "type": "bool" + } + ], + "name": "testMultiParams", + "output": "void", + "type": "Action" + }, + { + "constant": false, + "input": [ + { + "name": "input", + "type": "uint8[]" + } + ], + "name": "setBytes", + "output": "void", + "type": "Action" + }, + { + "constant": true, + "input": [], + "name": "getBytes", + "output": "uint8[]", + "type": "Action" + }, + { + "constant": false, + "input": [ + { + "name": "input", + "type": "string[10]" + } + ], + "name": "setArray", + "output": "void", + "type": "Action" + }, + { + "constant": true, + "input": [], + "name": "getArray", + "output": "string[10]", + "type": "Action" + }, + { + "constant": false, + "input": [ + { + "name": "input", + "type": "pair" + } + ], + "name": "setPair", + "output": "void", + "type": "Action" + }, + { + "constant": false, + "input": [ + { + "name": "input", + "type": "set" + } + ], + "name": "setSet", + "output": "void", + "type": "Action" + }, + { + "constant": true, + "input": [], + "name": "getSet", + "output": "set", + "type": "Action" + }, + { + "constant": true, + "input": [], + "name": "getFixedHash", + "output": "FixedHash<256>", + "type": "Action" + }, + { + "constant": false, + "input": [ + { + "name": "input", + "type": "list" + } + ], + "name": "setList", + "output": "void", + "type": "Action" + }, + { + "constant": true, + "input": [], + "name": "getList", + "output": "list", + "type": "Action" + }, + { + "constant": false, + "input": [ + { + "name": "addr", + "type": "FixedHash<20>" + } + ], + "name": "setAddress", + "output": "void", + "type": "Action" + }, + { + "constant": true, + "input": [], + "name": "getAddress", + "output": "FixedHash<20>", + "type": "Action" + } +] \ No newline at end of file diff --git a/tests/wasm/example3/main.cpp b/tests/wasm/example3/main.cpp new file mode 100644 index 0000000..101a173 --- /dev/null +++ b/tests/wasm/example3/main.cpp @@ -0,0 +1,344 @@ +#include +#include +#include +using namespace platon; + +class message { + public: + std::string head; + PLATON_SERIALIZE(message, (head)) +}; + +class my_message : public message { + public: + std::string body; + std::string end; + PLATON_SERIALIZE_DERIVED(my_message, message, (body)(end)) +}; + + +CONTRACT JSSDKTestContract: public platon::Contract +{ + PLATON_EVENT1(transfer,std::string,std::string) + PLATON_EVENT1(setUint16Evt,std::string,std::string,uint16_t) + PLATON_EVENT2(setUint32Evt,std::string,uint32_t,std::string,uint32_t,uint32_t) + public: + ACTION void init() + { + // do something to init. + } + + public: + + ACTION void setUint8(uint8_t input) + { + DEBUG("js_contract", "setUint8", input); + PLATON_EMIT_EVENT1(transfer,"js_contract", "event"); + tUint8.self() = input; + } + CONST uint8_t getUint8() + { + return tUint8.self(); + } + + ACTION void setUint16(uint16_t input) + { + DEBUG("js_contract", "setUint16", input); + PLATON_EMIT_EVENT1(setUint16Evt,"topic1","data1",input); + tUint16.self() = input; + } + CONST uint16_t getUint16() + { + return tUint16.self(); + } + + ACTION void setUint32(uint32_t input) + { + DEBUG("js_contract", "setUint32", input); + PLATON_EMIT_EVENT2(setUint32Evt,"topic1",input,"data1",input,input); + tUint32.self() = input; + } + CONST uint32_t getUint32() + { + return tUint32.self(); + } + + ACTION void setUint64(uint64_t input) + { + DEBUG("js_contract", "setUint64", input); + tUint64.self() = input; + } + CONST uint64_t getUint64() + { + return tUint64.self(); + } + + ACTION void setString(const std::string& input) + { + DEBUG("js_contract", "setString", input); + tString.self() = input; + } + CONST std::string getString() + { + return tString.self(); + } + + ACTION void setBool(bool input) + { + DEBUG("js_contract", "setBool", input); + tBool.self() = input; + } + CONST bool getBool() + { + return tBool.self(); + } + + ACTION void setChar(char input) + { + DEBUG("js_contract", "setChar", input); + tByte.self() = input; + } + CONST char getChar() + { + return tByte.self(); + } + + //ACTION void setU256(uint64_t input) + //{ + //DEBUG("js_contract", "setU256", input); + //tU256.self() = u256(input); + //} + //CONST std::string getU256() + //{ + //return to_string(tU256.self()); + //} + + + ACTION void setMessage(const message &msg) { + DEBUG("js_contract", "setMessage", msg.head); + sMessage.self() = msg; + } + CONST message getMessage() { + return sMessage.self(); + } + + ACTION void setMyMessage(const my_message &msg) { + sMyMessage.self() = msg; + DEBUG("js_contract", "setMyMessage", msg.head, msg.body, msg.end); + } + CONST my_message getMyMessage() { + return sMyMessage.self(); + } + + ACTION void setInt8(int8_t input) + { + DEBUG("js_contract", "setInt8", input); + tInt8.self() = input; + } + CONST int8_t getInt8() + { + return tInt8.self(); + } + + ACTION void setInt16(int16_t input) + { + DEBUG("js_contract", "setInt16", input); + tInt16.self() = input; + } + CONST int16_t getInt16() + { + return tInt16.self(); + } + + ACTION void setInt32(int32_t input) + { + DEBUG("js_contract", "setInt32", input); + tInt32.self() = input; + } + CONST int32_t getInt32() + { + return tInt32.self(); + } + + ACTION void setInt64(int64_t input) + { + DEBUG("js_contract", "setInt64", input); + tInt64.self() = input; + } + CONST int64_t getInt64() + { + return tInt64.self(); + } + + ACTION void setFloat(float input) { + DEBUG("js_contract", "setFloat", input); + tFloat.self() = input; + } + CONST float getFloat() { + return tFloat.self(); + } + ACTION void setDouble(double input) { + DEBUG("js_contract", "setDouble", input); + tDouble.self() = input; + } + CONST double getDouble() { + return tDouble.self(); + } + + ACTION void setVector(const std::vector& vec) { + for(auto iter = vec.begin(); iter != vec.end(); iter++) { + DEBUG("js_contract", "setVector", *iter); + } + sVector.self() = vec; + } + CONST std::vector getVector() { + return sVector.self(); + } + + ACTION void setMap(const std::map& input) { + for (auto iter=input.begin(); iter!=input.end(); iter++) { + DEBUG("js_contract", "setMap", iter->first, iter->second); + } + sMap.self() = input; + } + CONST std::map getMap() { + return sMap.self(); + } + + ACTION void testMultiParams(const message &msg, int32_t input1, bool input2) { + DEBUG("js_contract", "testMultiParams", msg.head, input1, input2); + sMessage.self() = msg; + tInt32.self() = input1; + tBool.self() = input2; + } + + ACTION void setBytes(const bytes input) { + for (int i=0; i& input) { + for(auto iter = input.begin(); iter != input.end(); iter++) { + DEBUG("js_contract", "setArray", *iter); + } + sArray.self() = input; + } + CONST std::array getArray() { + return sArray.self(); + } + ACTION void setPair(const std::pair& input) { + DEBUG("js_contract", "setPair", input.first, input.second); + sPair.self() = input; + } + CONST std::pair getPair() { + return sPair.self(); + } + ACTION void setSet(const std::set& input) { + for(auto iter = input.begin(); iter != input.end(); iter++) { + DEBUG("js_contract", "setSet", *iter); + } + sSet.self() = input; + } + CONST std::set getSet() { + return sSet.self(); + } + //ACTION void setU160(u160 input) + //{ + //DEBUG("js_contract", "setU160", input); + //sU160.self() = input; + //} + //CONST u160 getU160() + //{ + //return sU160.self(); + //} + //ACTION void setU256new(u256 input) + //{ + //DEBUG("js_contract", "setU256new", input); + //sU256.self() = input; + //} + //CONST u256 getU256new() + //{ + //return sU256.self(); + //} + //ACTION void setBigInt(bigint input) + //{ + //DEBUG("js_contract", "setBigInt", input); + //sBigint.self() = input; + //} + //CONST bigint getBigInt() + //{ + //return sBigint.self(); + //} + ACTION void setFixedHash(const FixedHash<256>& input) { + //DEBUG("js_contract", "setFixedHash", input); + sFixedHash.self() = input; + } + CONST FixedHash<256> getFixedHash() { + return sFixedHash.self(); + } + + ACTION void setList(const std::list& input) { + for(auto iter = input.begin(); iter != input.end(); iter++) { + DEBUG("js_contract", "setList", *iter); + } + sList.self() = input; + } + CONST std::list getList() { + return sList.self(); + } + ACTION void setAddress(const Address& addr) { + sAddress.self() = addr; + } + CONST Address getAddress() { + return sAddress.self(); + } + + private: + platon::StorageType<"suint1"_n, uint8_t> tUint8; + platon::StorageType<"suint2"_n, uint16_t> tUint16; + platon::StorageType<"suint3"_n, uint32_t> tUint32; + platon::StorageType<"suint5"_n, uint64_t> tUint64; + platon::StorageType<"sstring"_n, std::string> tString; + platon::StorageType<"sbool"_n, bool> tBool; + platon::StorageType<"sbyte"_n, char> tByte; + //platon::StorageType<"su123"_n, u256> tU256; + + platon::StorageType<"message"_n, message> sMessage; + platon::StorageType<"mymessage"_n, my_message> sMyMessage; + + platon::StorageType<"sint1"_n, int8_t> tInt8; + platon::StorageType<"sint2"_n, int16_t> tInt16; + platon::StorageType<"sint3"_n, int32_t> tInt32; + platon::StorageType<"sint5"_n, int64_t> tInt64; + platon:: StorageType<"storagefloat"_n,float> tFloat; + platon:: StorageType<"storagedouble"_n,double> tDouble; + + platon::StorageType<"vectorvar"_n, std::vector> sVector; + platon::StorageType<"mapvar"_n,std::map> sMap; + + platon::StorageType<"bytesvar"_n, bytes> sBytes; + platon::StorageType<"arrayvar"_n, std::array> sArray; + platon::StorageType<"pairvar"_n, std::pair> sPair; + platon::StorageType<"setvar"_n, std::set> sSet; + //platon::StorageType<"u111var"_n, u160> sU160; + //platon::StorageType<"u222var"_n, u256> sU256; + //platon::StorageType<"bigintvar"_n, bigint> sBigint; + platon::StorageType<"fixedhashvar"_n, FixedHash<256>> sFixedHash; + platon::StorageType<"listvar"_n, std::list> sList; + platon::StorageType<"address"_n, Address> sAddress; +}; + +PLATON_DISPATCH(JSSDKTestContract,(init) +(setUint8)(getUint8)(setUint16)(getUint16)(setUint32)(getUint32)(setUint64)(getUint64) +(setString)(getString)(setBool)(getBool)(setChar)(getChar) +(setMessage)(getMessage)(setMyMessage)(getMyMessage) +(setInt8)(getInt8)(setInt16)(getInt16)(setInt32)(getInt32)(setInt64)(getInt64) +(setFloat)(getFloat)(setDouble)(getDouble)(setVector)(getVector)(setMap)(getMap)(testMultiParams) +(setBytes)(getBytes)(setArray)(getArray)(setPair)(getPair)(setSet)(getSet) +(setFixedHash)(getFixedHash) +(setList)(getList)(setAddress)(getAddress)) + diff --git a/tests/wasm/example3/main.wasm b/tests/wasm/example3/main.wasm new file mode 100644 index 0000000..cfa9886 Binary files /dev/null and b/tests/wasm/example3/main.wasm differ diff --git a/tests/wasm_unit_test.py b/tests/wasm_unit_test.py new file mode 100644 index 0000000..a624775 --- /dev/null +++ b/tests/wasm_unit_test.py @@ -0,0 +1,225 @@ +import rlp +import time +import random as _ +import binascii +import json +import os +from hexbytes import HexBytes +from client_sdk_python import Web3, HTTPProvider +from client_sdk_python.eth import PlatON +from client_sdk_python.utils.transactions import get_block_gas_limit + +w3 = Web3(HTTPProvider("http://192.168.21.75:6789")) +platon = PlatON(w3) +from_address = 'lat1c6a7wyxedrs3pgmf5ansd3xlrkd7zyhvy94sn3' +gas = get_block_gas_limit(w3) - 1 + +# unlock account +# w3.personal.unlockAccount('lat1c6a7wyxedrs3pgmf5ansd3xlrkd7zyhvy94sn3', "123456", 3600*100) + + +class HexJsonEncoder(json.JSONEncoder): + def default(self, obj): + if isinstance(obj, HexBytes): + return obj.hex() + return super().default(obj) + + +def hex_json_encode(dict_): + return json.dumps(dict(dict_), cls=HexJsonEncoder, indent=2) + + +def wasm_deploy(wasm_bin_path, *args, **kwargs): + wasm_bin = os.path.join(wasm_bin_path, 'main.wasm') + abi_path = os.path.join(wasm_bin_path, 'main.abi.json') + with open(wasm_bin, 'rb') as f: + contents = f.read() + bytecode = binascii.b2a_hex(contents) + with open(abi_path, 'r') as f: + abi = json.load(f) + wasm_obj = platon.wasmcontract(abi=abi, bytecode=bytecode, vmtype=1) + tx_hash = wasm_obj.constructor(*args, **kwargs).transact( + { + 'from': from_address, + 'gas': gas, + "gasPrice": 1000000000, + "chainId": 100 + } + ) + + tx_receipt = platon.waitForTransactionReceipt(tx_hash) + print(f'tx_receipt:{hex_json_encode(tx_receipt)}') + contract_address = tx_receipt['contractAddress'] + print(f'contract_address is:{contract_address}') + print(f'abi is:{abi}') + return contract_address, abi + + +def contract_transfer_call_add(contract_address, abi): + wasm_contract_obj = platon.wasmcontract(address=contract_address, abi=abi, vmtype=1) + tx_events_hash = wasm_contract_obj.functions.calcAdd(0, 1).transact({'from': from_address, 'gas': gas}) + tx_events_receipt = platon.waitForTransactionReceipt(tx_events_hash) + print(tx_events_receipt) + + topic_param = wasm_contract_obj.events.Add().processReceipt(tx_events_receipt) + print(topic_param) + + +def contract_transfer_put_element(contract_address, abi): + wasm_contract_obj = platon.wasmcontract(address=contract_address, abi=abi, vmtype=1) + for i in [11, 12, 13]: + tx_hash = wasm_contract_obj.functions.putElement(i).transact({'from': from_address, 'gas': gas}) + tx_events_receipt = platon.waitForTransactionReceipt(tx_hash) + # print(f'contract_transfer_put_element receipt:{hex_json_encode(tx_events_receipt)}') + result = wasm_contract_obj.functions.getParams().call() + print(f'contract_transfer_put_element:{result}') + + +def contract_transfer_init_sum(contract_address, abi): + wasm_contract_obj = platon.wasmcontract(address=contract_address, abi=abi, vmtype=1) + element_list = wasm_contract_obj.functions.getParams().call() + print(f'element_list:{element_list}') + if element_list: + result = wasm_contract_obj.functions.makeCall().call() + print(result) + else: + return 0 + + +def decode_vector_type(contract_address, abi): + wasm_contract_obj = platon.wasmcontract(address=contract_address, abi=abi, vmtype=1) + tx_hash = wasm_contract_obj.functions.clearElement().transact({'from': from_address, 'gas': gas}) + tx_receipt = platon.waitForTransactionReceipt(tx_hash) + topic_param = wasm_contract_obj.events.clear().processReceipt(tx_receipt) + print(topic_param) + + +class TypeTest: + def __init__(self, contract_address, abi, type_=None, bit=None): + type_list = ['Bool', 'String', 'Uint', 'Array', 'List', 'Map', 'Vector', 'Message', 'Bytes', 'Set', + 'MyMessage', 'Double', 'Pair', 'Int', 'FixedHash'] + if type_ and type_ not in type_list: + print(f'not exits {type_}') + return + if bit is None: + bit = ['8'] + + self.functions = platon.wasmcontract(address=contract_address, abi=abi, vmtype=1).functions + self.type_ = type_ + self.bit = bit + + def batch_test(self): + self.get_and_set_uint() + self.get_and_set_bool() + self.get_and_set_other_type() + + def run(self): + if not self.type_: + self.batch_test() + else: + if self.type_ in ['Uint', 'Int']: + self.get_and_set_uint() + if self.type_ == 'Bool': + self.get_and_set_bool() + else: + self.get_and_set_other_type() + + @staticmethod + def tx_receipt_status(tx_hash, info): + tx_receipt = platon.waitForTransactionReceipt(tx_hash) + if not tx_receipt['status']: + print(f"bit is:{info},tx status\n:{hex_json_encode(tx_receipt)}") + + def get_method_boj(self, method_name_suffix): + return getattr(self.functions, f'set{method_name_suffix}'), getattr(self.functions, f'get{method_name_suffix}') + + def get_and_set_uint(self): + uint_data = { + '8': [0, 255, _.randint(0, 255)], + '16': [0, 65535, _.randint(0, 65535)], + '32': [0, 4294967295, _.randint(0, 4294967295)], + '64': [0, 18446744073709551615, _.randint(0, 9007199254740991)] + } + int_data = { + '8': [-128, 127, _.randint(-128, 127)], + '16': [-32767, 32767, _.randint(-32767, 32768)], + '32': [-2147483648, 2147483647, _.randint(-2147483648, 2147483647)], + '64': [-9223372036854775808, 9223372036854775807, _.randint(-9223372036854775808, 9223372036854775807)] + } + test_data = {'Uint': uint_data, 'Int': int_data} + int_or_uint = [self.type_] if self.type_ else ['Uint', 'Int'] + for int_ in int_or_uint: + for bit_ in self.bit: + set_uint, get_uint = self.get_method_boj(f'{int_}{bit_}') + for num in test_data[int_][bit_]: + tx_hash = set_uint(num).transact({'from': from_address, 'gas': gas}) + info = f'get_and_set_{int_},bit:{bit_},set num:{num}' + self.tx_receipt_status(tx_hash, info) + time.sleep(2) + print(f"get_and_set_{int_},bit is:{bit_},set num:{num},get result:{get_uint().call()}") + + def get_and_set_bool(self): + for bool_ in [True, False, True]: + set_bool, get_bool = self.get_method_boj('Bool') + tx_hash = set_bool(bool_).transact({'from': from_address, 'gas': gas}) + self.tx_receipt_status(tx_hash, f'get_and_set_bool,test value:{bool_}') + time.sleep(2) + result = get_bool().call() + print(result) + + def other_type(self, type_, param): + set_value, get_value = self.get_method_boj(type_) + tx_hash = set_value(param).transact({'from': from_address, 'gas': gas}) + self.tx_receipt_status(tx_hash, f'get_and_set_other_type,type is {self.type_},test param:{param}') + result = get_value().call() + print(f'type is:{type_},set param:{param},get result:{result}') + + def get_and_set_other_type(self): + params = { + 'String': 'test string type', + 'Array': ['hello', 'world', 'may', 'the', 'force', 'with', 'you', 'impossible', 'dancing', 'in dark'], + 'List': ["1", "hello", "world"], + 'Map': [['hello world', 'may the force with you'], ['how are you', 'fine,thanks and you ? Oh,ok']], + 'Vector': [0, 65535, _.randint(0, 65535), _.randint(0, 65535), _.randint(0, 65535), _.randint(0, 65535)], + 'Message': ['HelloWorld'], + 'Set': ['str1', 'str2', 'str3'], + 'MyMessage': [['HelloWorld'], 'Wasm', 'Good'], # struct + 'Pair': ['test setPair', -435716456], + 'FixedHash': 'd28c7465737420736574506169728433f102cf', + # 'Double': 1.45, # wasm不支持 + } + if self.type_ in ['Uint', 'Int']: + return + if self.type_: + self.other_type(self.type_, params[self.type_]) + else: + for type_, param in params.items(): + self.other_type(type_, param) +# region test easy deploy and sum int number +# con_address, abi_info = wasm_deploy('./wasm/example1') +# abi_info = [{'anonymous': False, 'input': [{'name': 'topic1', 'type': 'string'}, {'name': 'topic2', 'type': 'int32'}], 'name': 'Add', 'topic': 2, 'type': 'Event'}, {'constant': False, 'input': [], 'name': 'init', 'output': 'void', 'type': 'Action'}, {'constant': False, 'input': [], 'name': 'makeNumber', 'output': 'void', 'type': 'Action'}, {'constant': False, 'input': [], 'name': 'deleteNumber', 'output': 'void', 'type': 'Action'}, {'constant': True, 'input': [], 'name': 'get_Numbers', 'output': 'list', 'type': 'Action'}, {'constant': False, 'input': [{'name': 'a', 'type': 'int32'}, {'name': 'b', 'type': 'int32'}], 'name': 'calcAdd', 'output': 'int32', 'type': 'Action'}] +# con_address='lat1zt5rmejmzww5nglluq459r2ffsld5zamda7xk7' +# contract_transfer_call_add(con_address, abi_info) +# endregion + +# region have init params deploy +# con_address, abi_info = wasm_deploy('./wasm/example2',[[1,2,3]]) +# con_address = 'lat1a2mgy40v88lfjpzl7nhvt4fnucq2v7xp307k35' +# abi_info = [{'constant': False, 'input': [{'name': 'ele', 'type': 'int32'}], 'name': 'putElement', 'output': 'void', 'type': 'Action'}, {'constant': True, 'input': [], 'name': 'makeCall', 'output': 'int32', 'type': 'Action'}, {'constant': False, 'input': [], 'name': 'clearElement', 'output': 'void', 'type': 'Action'}, {'anonymous': False, 'input': [{'name': 'topic', 'type': 'string'}, {'name': 'arg1', 'type': 'uint32'}], 'name': 'Add', 'topic': 1, 'type': 'Event'}, {'anonymous': False, 'input': [{'name': 'topic', 'type': 'string'}, {'name': 'arg1', 'type': 'int32'}], 'name': 'call2', 'topic': 1, 'type': 'Event'}, {'anonymous': False, 'input': [{'name': 'topic', 'type': 'string'}, {'name': 'arg1', 'type': 'int32'}], 'name': 'put', 'topic': 1, 'type': 'Event'}, {'anonymous': False, 'input': [{'name': 'topic', 'type': 'string'}, {'name': 'arg1', 'type': 'uint32'}], 'name': 'clear', 'topic': 1, 'type': 'Event'}, {'baseclass': [], 'fields': [{'name': 'myParams', 'type': 'int32[]'}], 'name': 'inputParams', 'type': 'struct'}, {'constant': False, 'input': [{'name': 'ipa', 'type': 'inputParams'}], 'name': 'init', 'output': 'void', 'type': 'Action'}, {'constant': True, 'input': [], 'name': 'getParams', 'output': 'int32[]', 'type': 'Action'}, {'constant': False, 'input': [], 'name': 'AddCalc', 'output': 'int32', 'type': 'Action'}, {'constant': True, 'input': [{'name': 'a', 'type': 'int32'}, {'name': 'b', 'type': 'int32'}], 'name': 'makeCall2', 'output': 'int32', 'type': 'Action'}] +# contract_transfer_put_element(con_address,abi_info) +# contract_transfer_init_sum(con_address,abi_info) +# decode_vector_type(con_address, abi_info) +# endregion + +# region comprehensive test +# con_address, abi_info = wasm_deploy('./wasm/example3') +con_address = 'lat1vdtncj4m0fws6gad0pd8rxcke75yawz6qds5ax' +abi_info = [{'constant': True, 'input': [], 'name': 'getVector', 'output': 'uint16[]', 'type': 'Action'}, {'constant': False, 'input': [{'name': 'input', 'type': 'int8'}], 'name': 'setChar', 'output': 'void', 'type': 'Action'}, {'constant': False, 'input': [{'name': 'input', 'type': 'int8'}], 'name': 'setInt8', 'output': 'void', 'type': 'Action'}, {'constant': False, 'input': [{'name': 'input', 'type': 'uint8'}], 'name': 'setUint8', 'output': 'void', 'type': 'Action'}, {'constant': True, 'input': [], 'name': 'getPair', 'output': 'pair', 'type': 'Action'}, {'baseclass': [], 'fields': [{'name': 'head', 'type': 'string'}], 'name': 'message', 'type': 'struct'}, {'baseclass': ['message'], 'fields': [{'name': 'body', 'type': 'string'}, {'name': 'end', 'type': 'string'}], 'name': 'my_message', 'type': 'struct'}, {'constant': True, 'input': [], 'name': 'getMyMessage', 'output': 'my_message', 'type': 'Action'}, {'anonymous': False, 'input': [{'name': 'topic', 'type': 'string'}, {'name': 'arg1', 'type': 'string'}], 'name': 'transfer', 'topic': 1, 'type': 'Event'}, {'anonymous': False, 'input': [{'name': 'topic', 'type': 'string'}, {'name': 'arg2', 'type': 'string'}, {'name': 'arg1', 'type': 'uint16'}], 'name': 'setUint16Evt', 'topic': 1, 'type': 'Event'}, {'constant': False, 'input': [{'name': 'input', 'type': 'FixedHash<256>'}], 'name': 'setFixedHash', 'output': 'void', 'type': 'Action'}, {'anonymous': False, 'input': [{'name': 'topic1', 'type': 'string'}, {'name': 'topic2', 'type': 'uint32'}, {'name': 'arg3', 'type': 'string'}, {'name': 'arg2', 'type': 'uint32'}, {'name': 'arg1', 'type': 'uint32'}], 'name': 'setUint32Evt', 'topic': 2, 'type': 'Event'}, {'constant': False, 'input': [], 'name': 'init', 'output': 'void', 'type': 'Action'}, {'constant': True, 'input': [], 'name': 'getUint8', 'output': 'uint8', 'type': 'Action'}, {'constant': False, 'input': [{'name': 'input', 'type': 'uint16'}], 'name': 'setUint16', 'output': 'void', 'type': 'Action'}, {'constant': True, 'input': [], 'name': 'getUint16', 'output': 'uint16', 'type': 'Action'}, {'constant': False, 'input': [{'name': 'input', 'type': 'uint32'}], 'name': 'setUint32', 'output': 'void', 'type': 'Action'}, {'constant': True, 'input': [], 'name': 'getUint32', 'output': 'uint32', 'type': 'Action'}, {'constant': False, 'input': [{'name': 'input', 'type': 'uint64'}], 'name': 'setUint64', 'output': 'void', 'type': 'Action'}, {'constant': True, 'input': [], 'name': 'getUint64', 'output': 'uint64', 'type': 'Action'}, {'constant': False, 'input': [{'name': 'input', 'type': 'string'}], 'name': 'setString', 'output': 'void', 'type': 'Action'}, {'constant': True, 'input': [], 'name': 'getString', 'output': 'string', 'type': 'Action'}, {'constant': False, 'input': [{'name': 'input', 'type': 'bool'}], 'name': 'setBool', 'output': 'void', 'type': 'Action'}, {'constant': True, 'input': [], 'name': 'getBool', 'output': 'bool', 'type': 'Action'}, {'constant': True, 'input': [], 'name': 'getChar', 'output': 'int8', 'type': 'Action'}, {'constant': False, 'input': [{'name': 'msg', 'type': 'message'}], 'name': 'setMessage', 'output': 'void', 'type': 'Action'}, {'constant': True, 'input': [], 'name': 'getMessage', 'output': 'message', 'type': 'Action'}, {'constant': False, 'input': [{'name': 'msg', 'type': 'my_message'}], 'name': 'setMyMessage', 'output': 'void', 'type': 'Action'}, {'constant': True, 'input': [], 'name': 'getInt8', 'output': 'int8', 'type': 'Action'}, {'constant': False, 'input': [{'name': 'input', 'type': 'int16'}], 'name': 'setInt16', 'output': 'void', 'type': 'Action'}, {'constant': True, 'input': [], 'name': 'getInt16', 'output': 'int16', 'type': 'Action'}, {'constant': False, 'input': [{'name': 'input', 'type': 'int32'}], 'name': 'setInt32', 'output': 'void', 'type': 'Action'}, {'constant': True, 'input': [], 'name': 'getInt32', 'output': 'int32', 'type': 'Action'}, {'constant': False, 'input': [{'name': 'input', 'type': 'int64'}], 'name': 'setInt64', 'output': 'void', 'type': 'Action'}, {'constant': True, 'input': [], 'name': 'getInt64', 'output': 'int64', 'type': 'Action'}, {'constant': False, 'input': [{'name': 'input', 'type': 'float'}], 'name': 'setFloat', 'output': 'void', 'type': 'Action'}, {'constant': True, 'input': [], 'name': 'getFloat', 'output': 'float', 'type': 'Action'}, {'constant': False, 'input': [{'name': 'input', 'type': 'double'}], 'name': 'setDouble', 'output': 'void', 'type': 'Action'}, {'constant': True, 'input': [], 'name': 'getDouble', 'output': 'double', 'type': 'Action'}, {'constant': False, 'input': [{'name': 'vec', 'type': 'uint16[]'}], 'name': 'setVector', 'output': 'void', 'type': 'Action'}, {'constant': False, 'input': [{'name': 'input', 'type': 'map'}], 'name': 'setMap', 'output': 'void', 'type': 'Action'}, {'constant': True, 'input': [], 'name': 'getMap', 'output': 'map', 'type': 'Action'}, {'constant': False, 'input': [{'name': 'msg', 'type': 'message'}, {'name': 'input1', 'type': 'int32'}, {'name': 'input2', 'type': 'bool'}], 'name': 'testMultiParams', 'output': 'void', 'type': 'Action'}, {'constant': False, 'input': [{'name': 'input', 'type': 'uint8[]'}], 'name': 'setBytes', 'output': 'void', 'type': 'Action'}, {'constant': True, 'input': [], 'name': 'getBytes', 'output': 'uint8[]', 'type': 'Action'}, {'constant': False, 'input': [{'name': 'input', 'type': 'string[10]'}], 'name': 'setArray', 'output': 'void', 'type': 'Action'}, {'constant': True, 'input': [], 'name': 'getArray', 'output': 'string[10]', 'type': 'Action'}, {'constant': False, 'input': [{'name': 'input', 'type': 'pair'}], 'name': 'setPair', 'output': 'void', 'type': 'Action'}, {'constant': False, 'input': [{'name': 'input', 'type': 'set'}], 'name': 'setSet', 'output': 'void', 'type': 'Action'}, {'constant': True, 'input': [], 'name': 'getSet', 'output': 'set', 'type': 'Action'}, {'constant': True, 'input': [], 'name': 'getFixedHash', 'output': 'FixedHash<256>', 'type': 'Action'}, {'constant': False, 'input': [{'name': 'input', 'type': 'list'}], 'name': 'setList', 'output': 'void', 'type': 'Action'}, {'constant': True, 'input': [], 'name': 'getList', 'output': 'list', 'type': 'Action'}, {'constant': False, 'input': [{'name': 'addr', 'type': 'FixedHash<20>'}], 'name': 'setAddress', 'output': 'void', 'type': 'Action'}, {'constant': True, 'input': [], 'name': 'getAddress', 'output': 'FixedHash<20>', 'type': 'Action'}] +# type_test = TypeTest(con_address, abi_info, type_='Int',bit=['8', '16', '32', '64']) +# type_test = TypeTest(con_address, abi_info, type_='Double') + +# test all type +type_test = TypeTest(con_address, abi_info, bit=['8', '16', '32', '64']) +type_test.run() +# endregion + diff --git a/tests/wasmevent.py b/tests/wasmevent.py new file mode 100644 index 0000000..56502c9 --- /dev/null +++ b/tests/wasmevent.py @@ -0,0 +1,86 @@ +from client_sdk_python import Web3,HTTPProvider +from client_sdk_python.eth import PlatON + +true = True +false = False + +# w3 = Web3(HTTPProvider("http://10.1.1.5:6789")) +# platon = PlatON(w3) +# print(w3.isConnected()) +# +# from_address = "lax1yjjzvjph3tw4h2quw6mse25y492xy7fzwdtqja" +# print(from_address) +# +# send_privatekey = "b7a7372e78160f71a1a75e03c4aa72705806a05cf14ef39c87fdee93d108588c" + +# bytecode = '608060405234801561001057600080fd5b50610169806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806301ad4d8714610046578063477a5c981461006a578063edd89c081461008e575b600080fd5b61004e6100bf565b604051808260ff1660ff16815260200191505060405180910390f35b6100726100d1565b604051808260ff1660ff16815260200191505060405180910390f35b6100bd600480360360208110156100a457600080fd5b81019080803560ff1690602001909291905050506100e7565b005b6000809054906101000a900460ff1681565b60008060009054906101000a900460ff16905090565b806000806101000a81548160ff021916908360ff1602179055508060ff167f6c2b4666ba8da5a95717621d879a77de725f3d816709b9cbe9f059b8f875e28460405160405180910390a25056fea265627a7a7231582090ef2e55c9c3e1fc6cc130590605b1904b7c91f07bf401c7463c6dcebe70a96e64736f6c634300050c0032' +# +# abi = [{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_var","type":"uint256"}],"name":"MyEvent","type":"event"},{"constant":true,"inputs":[],"name":"_myVar","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint8","name":"_var","type":"uint8"}],"name":"setVar","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getVar","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"}] + +w3 = Web3(HTTPProvider("http://10.1.1.2:6789")) +platon = PlatON(w3) +print(w3.isConnected()) + +from_address = "lax1uqug0zq7rcxddndleq4ux2ft3tv6dqljphydrl" +print(from_address) + +send_privatekey = "983759fe9aac227c535b21d78792d79c2f399b1d43db46ae6d50a33875301557" + +bytecode='0061736d01000000015c1060027f7f0060017f017f60027f7f017f60017f0060037f7f7f017f60037f7f7f0060047f7f7f7f0060000060047f7f7f7f017f60027f7e0060017f017e60037f7e7e0060037f7e7e017f60017e017f60057f7f7f7f7f006000017f02ce010903656e760c706c61746f6e5f70616e6963000703656e760b706c61746f6e5f73686133000603656e7617706c61746f6e5f6765745f696e7075745f6c656e677468000f03656e7610706c61746f6e5f6765745f696e707574000303656e7617706c61746f6e5f6765745f73746174655f6c656e677468000203656e7610706c61746f6e5f6765745f7374617465000803656e7610706c61746f6e5f7365745f7374617465000603656e760c706c61746f6e5f6576656e74000603656e760d706c61746f6e5f72657475726e000003cd01cb010700020200040000010202020302020500000e000000020001000200010002000001020600020002000200000204000002010102040506000303010400050402050500000104020503010001040c00040b01000004080304000107070704050a0a030103010101010101010d09010000000003000100020100010001010001010a0d09000100000100000201000100010001000001000100010003010001000108030100020100090001030100010100000c0b0208000300000003030105070501010206000600000000000405017001050505030100020608017f0141908c040b073904066d656d6f72790200115f5f7761736d5f63616c6c5f63746f727300090f5f5f66756e63735f6f6e5f65786974006506696e766f6b650063090a010041010b04202124250af0b902cb01050010c7010baa0301097f230041c0016b22022400200241b908100b2104200241e8006a4102100c2103200241d8006a2004100d200241c8006a2000100d200241406b4100360200200241386a4200370300200241306a420037030020024200370328200241286a20022802582204200228025c100e20022802482205200228024c100e210620032002280228100f2003200241d8006a10102003200241c8006a1010200328020c200341106a28020047044010000b2003280204210720032802002108200241106a1011210020024180016a200110122101200241a8016a4100360200200241a0016a420037030020024198016a4200370300200242003703900120024190016a41001013200241b0016a200110121014410110132109200228029001210a200941046a10152000200a100f20004101101620024190016a200110121017220028020c200041106a28020047044010000b20082007200028020020002802041007200028020c22010440200020013602100b200641046a1015200504402002200536024c0b200404402002200436025c0b200328020c22000440200320003602100b200241c0016a24000b910101027f20004200370200200041086a410036020020012102024003402002410371044020022d0000450d02200241016a21020c010b0b2002417c6a21020340200241046a22022802002203417f73200341fffdfb776a7141808182847871450d000b0340200341ff0171450d01200241016a2d00002103200241016a21020c000b000b20002001200220016b105020000b1d0020001051200041146a41003602002000420037020c2000200110160b8b0101037f230041306b22032400200341186a1011220220011052100f2002200341086a200110121017220128020c200141106a28020047044010000b200041003602082000420037020020012802042102200128020021042000412010532004200220002802002202200028020420026b1001200128020c22000440200120003602100b200341306a24000b8b0101017f024020012002460440410121030c010b4101210302400240200220016b2202410146044020012c0000417f4c0d010c030b200241374b0d010b200241016a21030c010b2002105420026a41016a21030b027f200041186a28020022010440200041086a280200200041146a280200200110550c010b20000b2201200128020020036a36020020000b1300200028020820014904402000200110570b0b1600200020012802002200200128020420006b10581a0b190020001051200041146a41003602002000420037020c20000b4d01017f20004200370200200041086a2202410036020020012d0000410171450440200020012902003702002002200141086a28020036020020000f0b200020012802082001280204105020000bc30c02077f027e230041306b22042400200041046a2107027f20014101460440200041086a280200200041146a280200200041186a220228020022031055280200210120022003417f6a3602002007105a4180104f044020072000410c6a280200417c6a105b0b200141384f047f2001105420016a0520010b41016a2102200041186a28020022010440200041086a280200200041146a280200200110550c020b20000c010b02402007105a0d00200041146a28020022014180084f0440200020014180786a360214200041086a2201280200220228020021032001200241046a360200200420033602182007200441186a105c0c010b2000410c6a2802002202200041086a2802006b4102752203200041106a2205280200220620002802046b2201410275490440418020103a2105200220064704400240200028020c220120002802102202470d0020002802082203200028020422064b04402000200320012003200320066b41027541016a417e6d41027422026a105d220136020c2000200028020820026a3602080c010b200441186a200220066b2201410175410120011b22012001410276200041106a105e2102200028020c210320002802082101034020012003470440200228020820012802003602002002200228020841046a360208200141046a21010c010b0b200029020421092000200229020037020420022009370200200029020c21092000200229020837020c200220093702082002105f200028020c21010b200120053602002000200028020c41046a36020c0c020b02402000280208220120002802042202470d00200028020c2203200028021022064904402000200120032003200620036b41027541016a41026d41027422026a106022013602082000200028020c20026a36020c0c010b200441186a200620026b2201410175410120011b2201200141036a410276200041106a105e2102200028020c210320002802082101034020012003470440200228020820012802003602002002200228020841046a360208200141046a21010c010b0b200029020421092000200229020037020420022009370200200029020c21092000200229020837020c200220093702082002105f200028020821010b2001417c6a2005360200200020002802082201417c6a22023602082002280200210220002001360208200420023602182007200441186a105c0c010b20042001410175410120011b20032005105e2102418020103a2106024020022802082201200228020c2203470d0020022802042205200228020022084b04402002200520012005200520086b41027541016a417e6d41027422036a105d22013602082002200228020420036a3602040c010b200441186a200320086b2201410175410120011b22012001410276200241106a280200105e21032002280208210520022802042101034020012005470440200328020820012802003602002003200328020841046a360208200141046a21010c010b0b2002290200210920022003290200370200200320093702002002290208210920022003290208370208200320093702082003105f200228020821010b200120063602002002200228020841046a360208200028020c2105034020002802082005460440200028020421012000200228020036020420022001360200200228020421012002200536020420002001360208200029020c21092000200229020837020c200220093702082002105f052005417c6a210502402002280204220120022802002203470d0020022802082206200228020c22084904402002200120062006200820066b41027541016a41026d41027422036a106022013602042002200228020820036a3602080c010b200441186a200820036b2201410175410120011b2201200141036a4102762002280210105e21062002280208210320022802042101034020012003470440200428022020012802003602002004200428022041046a360220200141046a21010c010b0b20022902002109200220042903183702002002290208210a20022004290320370208200420093703182004200a3703202006105f200228020421010b2001417c6a200528020036020020022002280204417c6a3602040c010b0b0b200441186a20071061200428021c410036020041012102200041186a0b2201200128020020026a360200200441306a240020000ba10101037f41012103024002400240200128020420012d00002202410176200241017122041b220241014d0440200241016b0d032001280208200141016a20041b2c0000417f4c0d010c030b200241374b0d010b200241016a21030c010b2002105420026a41016a21030b027f200041186a28020022010440200041086a280200200041146a280200200110550c010b20000b2201200128020020036a36020020000bea0101047f230041106b22042400200028020422012000280210220241087641fcffff07716a2103027f410020012000280208460d001a2003280200200241ff07714102746a0b2101200441086a20001061200428020c210203400240200120024604402000410036021420002802082103200028020421010340200320016b41027522024103490d022000200141046a22013602040c000b000b200141046a220120032802006b418020470d0120032802042101200341046a21030c010b0b2002417f6a220241014d04402000418004418008200241016b1b3602100b20002001105b200441106a24000b8e0201057f2001044020002802042105200041106a2802002202200041146a280200220349044020022001ad2005ad422086843702002000200028021041086a36021020000f0b027f41002002200028020c22046b410375220641016a2202200320046b2203410275220420042002491b41ffffffff01200341037541ffffffff00491b2204450d001a2004410374103a0b2102200220064103746a22032001ad2005ad4220868437020020032000280210200028020c22066b22016b2105200220044103746a2102200341086a2103200141014e044020052006200110361a0b20002002360214200020033602102000200536020c20000f0b200041c00110d201200041004100410110ce0120000b2c01017f20002001280208200141016a20012d0000220041017122021b2001280204200041017620021b10580bc80301087f230041c0016b22032400200341ac08100b2105200341e8006a4102100c2104200341d8006a2005100d200341c8006a2000100d200341406b4100360200200341386a4200370300200341306a420037030020034200370328200341286a20032802582205200328025c100e20032802482206200328024c100e210720042003280228100f2004200341d8006a10102004200341c8006a1010200428020c200441106a28020047044010000b2004280204210820042802002109200341106a1011210020034180016a200110122101200320023b018c01200341a8016a4100360200200341a0016a420037030020034198016a4200370300200342003703900120034190016a41001013200341b0016a200110121014220220032f018c0110192002410110132102200328029001210a200241046a10152000200a100f20004102101620034190016a200110121017220020032f018c01101a200028020c200041106a28020047044010000b20092008200028020020002802041007200028020c22010440200020013602100b200741046a1015200604402003200636024c0b200504402003200536025c0b200428020c22000440200420003602100b200341c0016a24000b0c0020002001ad420010561a0b0b0020002001ad420010590bf20301067f230041d0016b22052400200541086a419f08100b2107200541f0006a4103100c2106200541e0006a2007100d200541d0006a2000100d200541c8006a4100360200200541406b4200370300200541386a420037030020054200370330200541306a200528026022002005280264100e200528025022072005280254100e22082001101920062005280230100f2006200541e0006a10102006200541d0006a101020062001101a200628020c200641106a28020047044010000b200628020421092006280200210a200541186a1011210120054188016a20021012210220052004360298012005200336029401200541b8016a4100360200200541b0016a4200370300200541a8016a4200370300200542003703a001200541a0016a41001013200541c0016a2002101210142203200528029401101920032005280298011019200341011013210320052802a0012104200341046a101520012004100f200141031016200541a0016a2002101210172201200528029401101a2001200528029801101a200128020c200141106a28020047044010000b200a2009200128020020012802041007200128020c22020440200120023602100b200841046a101520070440200520073602540b20000440200520003602640b200628020c22010440200620013602100b200541d0016a24000b2e01017f230041206b22022400200241106a418d08100b2002419908100b100a200020013a0010200241206a24000b3301017f230041206b22022400200241106a418008100b2002418708100b20011018200041286a20013b0100200241206a24000b3701017f230041206b22022400200241106a418008100b20012002418708100b20012001101b200041406b2001360200200241206a24000b930201047f20002001470440200128020420012d00002202410176200241017122041b2102200141016a210320012802082105410a21012005200320041b210420002d0000410171220304402000280200417e71417f6a21010b200220014d0440027f2003044020002802080c010b200041016a0b21012002044020012004200210490b200120026a41003a000020002d000041017104402000200236020420000f0b200020024101743a000020000f0b416f2103200141e6ffffff074d0440410b20014101742201200220022001491b220141106a4170712001410b491b21030b2003103a22012004200210c801200020023602042000200341017236020020002001360208200120026a41003a00000b20000b0d00200041b0016a20013a00000b0b00200041b0016a2c00000b230020002001101f1a2000410c6a2001410c6a101f1a200041186a200141186a101f1a0b25002000200110121a2000410c6a2001410c6a10121a200041186a200141186a10121a20000b0d00200041c8026a20013a00000b0b00200041c8026a2c00000b9e0101047f2000200147044020012802042203200128020022026b41017522042000280208200028020022016b4101754d0440200041046a21052004200028020420016b41017522004b04402002200220004101746a22002001104e1a20002003200510460f0b2005200220032001104e3602000f0b2001044020004100360208200042003702000b200020002004104f104c20022003200041046a10460b0b3e01017f2000420037020020004100360208200128020420012802006b2202044020002002410175104c20012802002001280204200041046a10460b20000b3001027f200141046a21032001280200210203402002200346044020004188046a20011029052002102a21020c010b0b0be00201067f230041206b22042400024020002001460d00200141046a21062001280200210102402000280208450d00200028020021032000200041046a3602002000410036020820002802042102200041003602042002410036020820032802042202200320021b2102034020022203450d0120012006470440200341106a200141106a101f21072003411c6a2001411c6a101f1a024020032802082202450440410021020c010b2003200228020022054604402002410036020020022802042205450d012005104321020c010b200241003602042005450d002005104321020b2000200441106a2007104421072000200428021020072003103f2001102a21010c010b0b0340200328020822030d000b200621010b034020012006460d01200441106a2000200141106a104a20002004410c6a2004280210220341106a104421022000200428020c20022003103f2001102a21010c000b000b200441206a24000b3601017f024020002802042201044003402001220028020022010d000c020b000b0340200020002802082200280200470d000b0b20000bd60101067f230041106b22022400200042003702042000200041046a2203360200200141046a21062001280200210103402001200646450440200141106a21050240027f027f0240024020032000280200460440200321040c010b2003103b220441106a2005103c450d010b20032802004504402002200336020c2003210420030c030b2002200436020c200441046a0c010b20002002410c6a2005103d0b22042802000d01200228020c0b2107200220002005104a2000200720042002280200103f0b2001102a21010c010b0b200241106a240020000b2300200041d0016a2001101f1a20004198016a20033a0000200041f8026a20023602000b920101047f2000200147044020012802042203200128020022026b22042000280208200028020022016b4d0440200041046a21052004200028020420016b22004b04402002200020026a2200200110471a20002003200510460f0b200520022003200110473602000f0b2001044020004100360208200042003702000b2000200020041048104520022003200041046a10460b0b3b01017f2000420037020020004100360208200128020420012802006b2202044020002002104520012802002001280204200041046a10460b20000b2601017f0340200241f800470440200020026a200120026a101f1a2002410c6a21020c010b0b0b2301017f0340200020026a200120026a10121a2002410c6a220241f800470d000b20000b130020002001101f1a2000200128020c36020c0b15002000200110121a2000200128020c36020c20000b3001027f200141046a210320012802002102034020022003460440200041f8066a20011034052002102a21020c010b0b0bd30201067f230041206b22042400024020002001460d00200141046a21062001280200210102402000280208450d00200028020021032000200041046a3602002000410036020820002802042102200041003602042002410036020820032802042202200320021b2102034020022203450d0120012006470440200341106a200141106a101f2107024020032802082202450440410021020c010b2003200228020022054604402002410036020020022802042205450d012005104321020c010b200241003602042005450d002005104321020b2000200441106a2007104421072000200428021020072003103f2001102a21010c010b0b0340200328020822030d000b200621010b034020012006460d01200441106a2000200141106a103e20002004410c6a2004280210220341106a104421022000200428020c20022003103f2001102a21010c000b000b200441206a24000bd60101067f230041106b22022400200042003702042000200041046a2203360200200141046a21062001280200210103402001200646450440200141106a21050240027f027f0240024020032000280200460440200321040c010b2003103b220441106a2005103c450d010b20032802004504402002200336020c2003210420030c030b2002200436020c200441046a0c010b20002002410c6a2005103d0b22042802000d01200228020c0b2107200220002005103e2000200720042002280200103f0b2001102a21010c010b0b200241106a240020000bfc0801067f03400240200020046a2105200120046a210320022004460d002003410371450d00200520032d00003a0000200441016a21040c010b0b200220046b210602402005410371220745044003402006411049450440200020046a2203200120046a2205290200370200200341086a200541086a290200370200200441106a2104200641706a21060c010b0b027f2006410871450440200120046a2103200020046a0c010b200020046a2205200120046a2204290200370200200441086a2103200541086a0b21042006410471044020042003280200360200200341046a2103200441046a21040b20064102710440200420032f00003b0000200341026a2103200441026a21040b2006410171450d01200420032d00003a000020000f0b024020064120490d002007417f6a220741024b0d00024002400240024002400240200741016b0e020102000b2005200120046a220328020022073a0000200541016a200341016a2f00003b0000200041036a2108200220046b417d6a2106034020064111490d03200420086a2203200120046a220541046a2802002202410874200741187672360200200341046a200541086a2802002207410874200241187672360200200341086a2005410c6a28020022024108742007411876723602002003410c6a200541106a2802002207410874200241187672360200200441106a2104200641706a21060c000b000b2005200120046a220328020022073a0000200541016a200341016a2d00003a0000200041026a2108200220046b417e6a2106034020064112490d03200420086a2203200120046a220541046a2802002202411074200741107672360200200341046a200541086a2802002207411074200241107672360200200341086a2005410c6a28020022024110742007411076723602002003410c6a200541106a2802002207411074200241107672360200200441106a2104200641706a21060c000b000b2005200120046a28020022073a0000200041016a21082004417f7320026a2106034020064113490d03200420086a2203200120046a220541046a2802002202411874200741087672360200200341046a200541086a2802002207411874200241087672360200200341086a2005410c6a28020022024118742007410876723602002003410c6a200541106a2802002207411874200241087672360200200441106a2104200641706a21060c000b000b200120046a41036a2103200020046a41036a21050c020b200120046a41026a2103200020046a41026a21050c010b200120046a41016a2103200020046a41016a21050b20064110710440200520032d00003a00002005200328000136000120052003290005370005200520032f000d3b000d200520032d000f3a000f200541106a2105200341106a21030b2006410871044020052003290000370000200541086a2105200341086a21030b2006410471044020052003280000360000200541046a2105200341046a21030b20064102710440200520032f00003b0000200541026a2105200341026a21030b2006410171450d00200520032d00003a00000b20000b2b01027f200141046a210203402002280200220341046a210220012003470d000b200041a80b6a200110380bbe0201057f024020002001460d00200041046a2102200141046a21030340200228020021020240027f4101200328020022032001460d001a20002002470d0141000b210402402000200246044020040d044114103a22054100360200200541086a200341086a10121a20052104410121060340200120032802042203460d024114103a220241086a200341086a10121a2002200436020020042002360204200641016a2106200221040c000b000b200228020022032000280200220128020436020420012802042003360200034020002002460d0420002000280208417f6a360208200228020421020c000b000b2000280200220220053602042005200236020020002004360200200420003602042000200028020820066a3602080c020b200241086a200341086a101f1a200241046a2102200341046a21030c000b000b0b840101037f200041003602082000200036020420002000360200200141046a2102037f20022802002203200146047f2000054114103a22024100360200200241086a200341086a10121a20022000360204200028020021042000200236020020022004360200200420023602042000200028020841016a360208200341046a21020c010b0b0b0b002000410120001b10620b3e01027f024020002802002201044003402001220228020422010d000c020b000b03402000280208220228020020004621012002210020010d000b0b20020bb20101067f02400240200128020420012d00002202410176200241017122031b2205200028020420002d00002202410176200241017122041b2206200520064922071b2202450d002000280208200041016a20041b21002001280208200141016a20031b210103402002450d0120002d0000220320012d00002204460440200141016a2101200041016a21002002417f6a21020c010b0b200320046b22020d010b417f200720062005491b21020b2002411f760b890101027f200041046a2103024020002802042200044002400340024002402002200041106a2204103c0440200028020022040d012001200036020020000f0b20042002103c450d03200041046a210320002802042204450d01200321000b20002103200421000c010b0b2001200036020020030f0b200120003602000c010b200120033602000b20030b2d01017f2000411c103a22033602002000200141046a360204200341106a200210121a200041086a41013a00000b480020032001360208200342003702002002200336020020002802002802002201044020002001360200200228020021030b2000280204200310402000200028020841016a3602080bec0101037f200120002001463a000c03400240024020002001460d00200128020822022d000c0d002002200228020822032802002204460440024020032802042204450d0020042d000c0d002004410c6a21010c030b20012002280200470440200210412002280208220228020821030b200241013a000c200341003a000c200310420f0b02402004450d0020042d000c0d002004410c6a21010c020b20012002280200460440200210422002280208220228020821030b200241013a000c200341003a000c200310410b0f0b200241013a000c200320002003463a000c200141013a0000200321010c000b000b5101027f200020002802042201280200220236020420020440200220003602080b200120002802083602082000280208220220022802002000474102746a200136020020002001360208200120003602000b5101027f200020002802002201280204220236020020020440200220003602080b200120002802083602082000280208220220022802002000474102746a200136020020002001360208200120003602040b1d01017f03402000220128020022000d00200128020422000d000b20010b5c01017f0240200028020422030440034002402002200341106a103c044020032802002200450d040c010b200328020422000d0020012003360200200341046a0f0b200021030c000b000b200041046a21030b2001200336020020030b2001017f20002001103a2202360200200020023602042000200120026a3602080b2800200120006b220141014e044020022802002000200110361a2002200228020020016a3602000b0b1900200120006b2201044020022000200110490b200120026a0b2e01017f2001200028020820002802006b2200410174220220022001491b41ffffffff07200041ffffffff03491b0b8d0301037f024020002001460d00200120006b20026b410020024101746b4d044020002001200210361a0c010b20002001734103712103027f024020002001490440200020030d021a410021030340200120036a2105200020036a2204410371450440200220036b210241002103034020024104490d04200320046a200320056a280200360200200341046a21032002417c6a21020c000b000b20022003460d04200420052d00003a0000200341016a21030c000b000b024020030d002001417f6a21040340200020026a22034103714504402001417c6a21032000417c6a2104034020024104490d03200220046a200220036a2802003602002002417c6a21020c000b000b2002450d042003417f6a200220046a2d00003a00002002417f6a21020c000b000b2001417f6a210103402002450d03200020026a417f6a200120026a2d00003a00002002417f6a21020c000b000b200320056a2101200320046a0b210303402002450d01200320012d00003a00002002417f6a2102200341016a2103200141016a21010c000b000b0b2c01017f20004128103a22033602002000200141046a360204200341106a2002104b200041086a41013a00000b16002000200110121a2000410c6a2001410c6a10121a0b2301017f20002001104d2202360200200020023602042000200220014101746a3602080b09002000410174103a0b2501017f200120006b220141017521032001044020022000200110490b200220034101746a0b2a002001200028020820002802006b220020002001491b41ffffffff07200041017541ffffffff03491b0b5b01027f02402002410a4d0440200020024101743a0000200041016a21030c010b200241106a4170712204103a21032000200236020420002004410172360200200020033602080b20032001200210c801200220036a41003a00000b160020004100360208200042003702002000410010570b5801027f230041306b22012400200141286a4100360200200141206a4200370300200141186a420037030020014200370310200141106a2001200010121014210020012802102102200041046a1015200141306a240020020bdd0101047f024020002802042203200028020022026b22042001490440200028020820036b200120046b22024f04400340200341003a00002000200028020441016a22033602042002417f6a22020d000c030b000b200020011048220104402001103a21050b200420056a220421030340200341003a0000200341016a21032002417f6a22020d000b200120056a210520042000280204200028020022046b22016b2102200141014e044020022004200110361a0b2000200536020820002003360204200020023602000f0b200420014d0d002000200120026a3602040b0b1e01017f03402000044020004108762100200141016a21010c010b0b20010b25002000200120026a417f6a220241087641fcffff07716a280200200241ff07714102746a0b900101027f4101210420014280015441002002501b450440034020012002845045044020024238862001420888842101200341016a2103200242088821020c010b0b200341384f047f2003105420036a0520030b41016a21040b027f200041186a28020022030440200041086a280200200041146a280200200310550c010b20000b2203200328020020046a36020020000b2f01017f2000280208200149044020011062200028020020002802041036210220002001360208200020023602000b0b7001017f4101210302400240024002402002410146044020012c000022024100480d012000200241ff017110d2010c040b200241374b0d01200221030b200020034180017341ff017110d2010c010b2000200210d301200221030b200020012003410010ce010b2000410110d00120000bcf0202037f027e02402001200284500440200041800110d2010c010b20014280015441002002501b4504402001210720022106034020062007845045044020064238862007420888842107200341016a2103200642088821060c010b0b0240200341384f04402003210403402004044020044108762104200541016a21050c010b0b200541c9004f044010000b2000200541b77f6a41ff017110d2012000200028020420056a10d101200028020420002802006a417f6a21052003210403402004450d02200520043a0000200441087621042005417f6a21050c000b000b200020034180017341ff017110d2010b2000200028020420036a10d101200028020420002802006a417f6a210303402001200284500d02200320013c0000200242388620014208888421012003417f6a2103200242088821020c000b000b20002001a741ff017110d2010b2000410110d0010b2801017f200028020820002802046b2201410874417f6a410020011b200028021420002802106a6b0b2501017f200028020821020340200120024645044020002002417c6a22023602080c010b0b0ba10202057f017e230041206b22052400024020002802082202200028020c2203470d0020002802042204200028020022064b04402000200420022004200420066b41027541016a417e6d41027422036a105d22023602082000200028020420036a3602040c010b200541086a200320066b2202410175410120021b220220024102762000410c6a105e2103200028020821042000280204210203402002200446450440200328020820022802003602002003200328020841046a360208200241046a21020c010b0b2000290200210720002003290200370200200320073702002000290208210720002003290208370208200320073702082003105f200028020821020b200220012802003602002000200028020841046a360208200541206a24000b2501017f200120006b220141027521032001044020022000200110490b200220034102746a0b4f01017f2000410036020c200041106a2003360200200104402001410274103a21040b200020043602002000200420024102746a22023602082000200420014102746a36020c2000200236020420000b2b01027f200028020821012000280204210203402001200247044020002001417c6a22013602080c010b0b0b1b00200120006b22010440200220016b22022000200110490b20020b4f01037f20012802042203200128021020012802146a220441087641fcffff07716a21022000027f410020032001280208460d001a2002280200200441ff07714102746a0b360204200020023602000b9b0101047f230041106b220124002001200036020c2000047f41880c200041086a2202411076220041880c2802006a220336020041840c41840c280200220420026a41076a417871220236020002400240200341107420024d044041880c200341016a360200200041016a21000c010b2000450d010b200040000d0010000b20042001410c6a4104103641086a0541000b2100200141106a240020000b090010c701106410650bc52602057f027e230041c0166b2201240010022200106222021003200141d00a6a200141086a20022000106622004100106702400240200141d00a6a10682205500d0041c208106920055104402000106a200141d00a6a106b106c0c020b41c708106920055104402000106d410247044010000b200141d00a6a200041011067200141d00a6a106e2100200141d00a6a106b22022000101c2002106c0c020b41d008106920055104402000106a200141d00a6a106b22032d00102102200141b8086a101122002002106f100f20002002101a200028020c200041106a28020047044010000b200028020020002802041008200028020c22020440200020023602100b2003106c0c020b41d908106920055104402000106d410247044010000b200141d00a6a200041011067200141d00a6a10702100200141d00a6a106b22022000101d2002106c0c020b41e308106920055104402000106a200141d00a6a106b220341286a2f01002102200141b8086a1011220020021071100f20002002101a200028020c200041106a28020047044010000b200028020020002802041008200028020c22020440200020023602100b2003106c0c020b41ed08106920055104402000106d410247044010000b200141d00a6a200041011067200141d00a6a10722100200141d00a6a106b22022000101e2002106c0c020b41f708106920055104402000106a200141d00a6a106b220341406b2802002102200141b8086a1011220020021073100f20002002101a200028020c200041106a28020047044010000b200028020020002802041008200028020c22020440200020023602100b2003106c0c020b418109106920055104402000106d410247044010000b200141d00a6a200041011067200141d00a6a10682105200141d00a6a106b220041d8006a20053703002000106c0c020b418b09106920055104402000106a200141d00a6a106b220241d8006a2903002105200141b8086a1011220020051074100f200020051075200028020c200041106a28020047044010000b200028020020002802041008200028020c22030440200020033602100b2002106c0c020b41950910692005510440200141b8066a107621022000106d410247044010000b200141d00a6a200041011067200141d00a6a20021077200141d00a6a106b220041f8006a200141b8086a20021012101f1a2000106c0c020b419f09106920055104402000106a200141a0046a200141d00a6a106b220241f8006a10122100200141b8086a1011220320001052100f2003200141b8066a200010121017220028020c200041106a28020047044010000b200028020020002802041008200028020c22030440200020033602100b2002106c0c020b41a90910692005510440200141003a00b8082000106d410247044010000b200141d00a6a200041011067200141d00a6a200141b8086a1078200141d00a6a106b22004198016a20012d00b8083a00002000106c0c020b41b109106920055104402000106a200141d00a6a106b22034198016a2d00002102200141b8086a101122002002106f100f20002002101a200028020c200041106a28020047044010000b200028020020002802041008200028020c22020440200020023602100b2003106c0c020b41b909106920055104402000410110790c020b41c1091069200551044020004102107a0c020b41c90910692005510440200141b8066a107b2000106d410247044010000b200141d00a6a200041011067200141d00a6a200141b8066a107c200141d00a6a106b220041d0016a200141b8086a200141b8066a1012101f1a2000106c0c020b41d409106920055104402000106a200141b8066a200141d00a6a106b220241d0016a10121a200141b8086a10112200200141b8066a107d100f2000200141b8066a107e200028020c200041106a28020047044010000b200028020020002802041008200028020c22030440200020033602100b2002106c0c020b41df0910692005510440200141b8066a4124107f1a200141b8066a10800121022000106d410247044010000b200141d00a6a200041011067200141d00a6a2002108101200141d00a6a106b22004190026a200141b8086a2002102310222000106c0c020b41ec09106920055104402000106a200141b8086a200141d00a6a106b22034190026a10232102200141b8066a101122002002108201100f20002002108301200028020c200041106a28020047044010000b200028020020002802041008200028020c22020440200020023602100b2003106c0c020b41f909106920055104402000410310790c020b41810a1069200551044020004104107a0c020b41890a106920055104402000106d410247044010000b200141d00a6a200041011067200141d00a6a1084012100200141d00a6a106b220241e0026a20003b01002002106c0c020b41920a106920055104402000106a200141d00a6a106b220341e0026a2e01002102200141b8086a101122002002108501100f20002002108601200028020c200041106a28020047044010000b200028020020002802041008200028020c22020440200020023602100b2003106c0c020b419b0a106920055104402000106d410247044010000b200141d00a6a200041011067200141d00a6a1087012100200141d00a6a106b220241f8026a20003602002002106c0c020b41a40a106920055104402000106a200141d00a6a106b220341f8026a2802002102200141b8086a101122002002108801100f20002002108601200028020c200041106a28020047044010000b200028020020002802041008200028020c22020440200020023602100b2003106c0c020b41ad0a106920055104402000106d410247044010000b200141d00a6a200041011067200141d00a6a1089012105200141d00a6a106b22004190036a20053703002000106c0c020b41b60a106920055104402000106a200141d00a6a106b22024190036a2903002105200141b8086a101122002005108a01100f20002005108b01200028020c200041106a28020047044010000b200028020020002802041008200028020c22030440200020033602100b2002106c0c020b41bf0a10692005510440200141003602c006200142003703b8062000106d410247044010000b200141d00a6a200041011067200141d00a6a200141b8066a108c01200141d00a6a106b220241e0036a200141b8086a200141b8066a102722001026200028020022030440200020033602040b2002106c20012802b8062200450d02200120003602bc060c020b41c90a106920055104402000106a200141b8066a200141d00a6a106b220341e0036a10272102200141b8086a101122002002108d01100f20002002108e01200028020c200041106a28020047044010000b200028020020002802041008200028020c22040440200020043602100b200228020022000440200220003602040b2003106c0c020b41d30a10692005510440200142003702bc062001200141b8066a4104723602b8062000106d410247044010000b200141d00a6a200041011067200141d00a6a200141b8066a108f01200141d00a6a106b2200200141b8086a200141b8066a102b10282000106c0c020b41da0a106920055104402000106a200141b8066a200141d00a6a106b22034188046a102b2102200141b8086a101122002002109001100f20002002109101200028020c200041106a28020047044010000b200028020020002802041008200028020c22020440200020023602100b2003106c0c020b41e10a10692005510440200141b8086a107b200141003a00c808200141003602c408200141c8086a21022000106d410447044010000b200141d00a6a200041011067200141d00a6a200141b8086a107c200141d00a6a2000410210672001200141d00a6a1087013602c408200141d00a6a200041031067200141d00a6a20021078200141d00a6a106b2100200141b8066a200141b8086a10121a2000200141b8066a20012802c40820012d00c808102c2000106c0c020b41f10a10692005510440200141003602a804200142003703a0042000106d410247044010000b200141d00a6a200041011067200141d00a6a200141a0046a109201200141d00a6a106b220341b0046a200141b8086a200141b8066a200141a0046a102e2200102e2202102d200228020022040440200220043602040b200028020022020440200020023602040b2003106c20012802a0042200450d02200120003602a4040c020b41fa0a106920055104402000106a200141b8066a200141d00a6a106b220341b0046a102e2102200141b8086a1011220020022802002002280204109301100f200020021010200028020c200041106a28020047044010000b200028020020002802041008200028020c22040440200020043602100b200228020022000440200220003602040b2003106c0c020b41830b10692005510440200141b8066a41f800107f1a200141b8066a10940121022000106d410247044010000b200141d00a6a200041011067200141d00a6a2002109501200141d00a6a106b220041c0056a200141b8086a20021030102f2000106c0c020b418c0b106920055104402000106a200141b8086a200141d00a6a106b220341c0056a10302102200141b8066a101122002002109601100f20002002109701200028020c200041106a28020047044010000b200028020020002802041008200028020c22020440200020023602100b2003106c0c020b41950b10692005510440200141b8066a10980121022000106d410247044010000b200141d00a6a200041011067200141d00a6a2002109901200141d00a6a106b220041d0066a200141b8086a2002103210312000106c0c020b419d0b106920055104402000106a200141b8066a200141d00a6a106b220341d0066a10322102200141b8086a101122002002109a01100f20002002109b01200028020c200041106a28020047044010000b200028020020002802041008200028020c22020440200020023602100b2003106c0c020b41a50b10692005510440200142003702bc062001200141b8066a4104723602b8062000106d410247044010000b200141d00a6a200041011067200141d00a6a200141b8066a109c01200141d00a6a106b2200200141b8086a200141b8066a103510332000106c0c020b41ac0b106920055104402000106a200141b8066a200141d00a6a106b220341f8066a10352102200141b8086a101122002002109d01100f20002002109e01200028020c200041106a28020047044010000b200028020020002802041008200028020c22020440200020023602100b2003106c0c020b41b30b10692005510440200141b8066a109f0121022000106d410247044010000b200141d00a6a200041011067200141d00a6a200210a001200141d00a6a106b2100200141206a200141b8066a41800210361a200141b8086a200141206a41800210361a20004190096a200141b8086a41800210361a2000106c0c020b41c00b106920055104402000106a200141a0026a200141d00a6a106b22024190096a41800210361a200141a0066a10112200200141a0026a10a101100f200141a0046a200141a0026a41800210361a200141b8066a200141a0046a41800210361a200141206a200141b8066a41800210361a200141b8086a200141206a41800210361a2000200141b8086a4180021058220028020c200041106a28020047044010000b200028020020002802041008200028020c22030440200020033602100b2002106c0c020b41cd0b10692005510440200141003602c0062001200141b8066a3602bc062001200141b8066a3602b8062000106d410247044010000b200141d00a6a200041011067200141d00a6a200141b8066a10a201200141d00a6a106b2200200141b8086a200141b8066a103922021037200210a3012000106c200141b8066a10a3010c020b41d50b106920055104402000106a200141b8066a200141d00a6a106b220341a80b6a10392102200141b8086a10112200200210a401100f2000200210a501200028020c200041106a28020047044010000b200028020020002802041008200028020c22040440200020043602100b200210a3012003106c0c020b41dd0b10692005510440200141b8086a10a60121022000106d410247044010000b200141d00a6a200041011067200141d00a6a200210a701200141d00a6a106b2100200141b0066a200141c8086a2802002202360200200141a8066a200141c0086a2903002205370300200120012903b80822063703a006200041d80b6a2006370300200041e00b6a2005370300200041e80b6a20023602002000106c0c020b41e80b10692005520d002000106a200141306a2200200141d00a6a106b220241e80b6a280000360200200141286a2203200241e00b6a2900003703002001200241d80b6a290000370320200141b8086a10112204200141206a10a801100f200141b0026a20002802002200360200200141a8026a200329030022053703002001200129032022063703a002200141a8046a2005370300200141b0046a2000360200200141a8066a2005370300200141b0066a2000360200200120063703a004200120063703a006200141c8066a2000360200200141c0066a2005370300200120063703b8062004200141b8066a41141058220028020c200041106a28020047044010000b200028020020002802041008200028020c22030440200020033602100b2002106c0c010b10000b200141c0166a24000b880101037f41f40b410136020041f80b2802002100034020000440034041fc0b41fc0b2802002201417f6a2202360200200141014845044041f40b4100360200200020024102746a22004184016a280200200041046a28020011030041f40b410136020041f80b28020021000c010b0b41fc0b412036020041f80b200028020022003602000c010b0b0b0d00200020012002411c10a9010bd00202067f017e230041106b220324002001280208220520024b0440200341086a200110cd0120012003280208200328020c10cb0136020c2003200110cd01410021052001027f410020032802002207450d001a410020032802042208200128020c2206490d001a200820062006417f461b210420070b360210200141146a2004360200200141003602080b200141106a210603402001280214210402402005200249044020040d01410021040b200020062802002004411410a9011a200341106a24000f0b2003200110cd0141002104027f410020032802002205450d001a410020032802042208200128020c2207490d001a200820076b2104200520076a0b210520012004360214200120053602102003200641002005200410cb0110cc012001200329030022093702102001200128020c2009422088a76a36020c2001200128020841016a22053602080c000b000b880102027f017e230041106b22012400200010aa0102400240200010ab01450d002000280204450d0020002802002d000041c001490d010b10000b200141086a200010ac01200128020c220041094f044010000b200128020821020340200004402000417f6a210020023100002003420886842103200241016a21020c010b0b200141106a240020030b3901027e42a5c688a1c89ca7f94b210103402000300000220250450440200041016a2100200142b383808080207e20028521010c010b0b20010b0e002000106d410147044010000b0bca2901097f230041406a22012400200042ddbe888dc5fcfca4987f370308200041003a0000200141286a1011220320002903081075200328020c200341106a28020047044010000b0240200328020022072003280204220810042205450d002001410036022020014200370318200141186a200510532007200820012802182204200128021c220620046b1005417f47044020002001200441016a20062004417f736a1066106e3a0010200521020b2004450d002001200436021c0b200328020c22040440200320043602100b2002450440200020002d00003a00100b41002102200041003b0118200041206a220442debe888dc5fcfca4987f370300200141286a1011220320042903001075200328020c200341106a28020047044010000b0240200328020022072003280204220810042205450d002001410036022020014200370318200141186a200510532007200820012802182204200128021c220620046b1005417f47044020002001200441016a20062004417f736a106610703b0128200521020b2004450d002001200436021c0b200328020c22040440200320043602100b2002450440200020002f01183b01280b4100210220004100360230200041386a220442dfbe888dc5fcfca4987f370300200141286a1011220320042903001075200328020c200341106a28020047044010000b0240200328020022072003280204220810042205450d002001410036022020014200370318200141186a200510532007200820012802182204200128021c220620046b1005417f47044020002001200441016a20062004417f736a10661072360240200521020b2004450d002001200436021c0b200328020c22040440200320043602100b2002450440200020002802303602400b20004200370348200041d0006a220242d9be888dc5fcfca4987f370300200141286a1011220320022903001075200328020c200341106a28020047044010000b0240200328020022072003280204220810042205450440410021040c010b410021042001410036022020014200370318200141186a200510532007200820012802182202200128021c220620026b1005417f47044020002001200241016a20062002417f736a10661068370358200521040b2002450d002001200236021c0b200328020c22020440200320023602100b2004450440200020002903483703580b200041e0006a10762109200041f0006a220242a7cea8ad82a0ff995b370300200041f8006a10762107200141286a1011220320022903001075200328020c200341106a28020047044010000b0240200328020022082003280204220610042205450440410021040c010b410021042001410036022020014200370318200141186a200510532008200620012802182202200128021c220620026b1005417f4704402001200241016a20062002417f736a106620071077200521040b2002450d002001200236021c0b200328020c22020440200320023602100b200445044020072009101f1a0b41002102200041003a00880120004190016a220442f4a2efb3f6e5b8ad03370300200141286a1011220320042903001075200328020c200341106a28020047044010000b0240200328020022072003280204220810042205450d002001410036022020014200370318200141186a200510532007200820012802182204200128021c220620046b1005417f4704402001200441016a20062004417f736a106620004198016a1078200521020b2004450d002001200436021c0b200328020c22040440200320043602100b2002450440200020002d0088013a0098010b200041003a00a001200041a8016a220342badda0b2f6c5fa8e033703002003200041b0016a10ad01450440200020002d00a0013a00b0010b200042003703b801200041c0016a4100360200200041b8016a10762109200041c8016a2202428aedabfdf7a698fe29370300200041d0016a220710761a200141286a1011220320022903001075200328020c200341106a28020047044010000b0240200328020022082003280204220610042205450440410021040c010b410021042001410036022020014200370318200141186a200510532008200620012802182202200128021c220620026b1005417f4704402001200241016a20062002417f736a10662007107c200521040b2002450d002001200236021c0b200328020c22020440200320023602100b200445044020072009101f1a0b41002102200041e0016a4124107f108001210920004188026a220442d4b7b1edebf7e3f66a37030020004190026a1080012107200141286a1011220320042903001075200328020c200341106a28020047044010000b0240200328020022082003280204220610042205450d002001410036022020014200370318200141186a200510532008200620012802182204200128021c220620046b1005417f4704402001200441016a20062004417f736a10662007108101200521020b2004450d002001200436021c0b200328020c22040440200320043602100b20024504402007200910220b200041003a00b802200041c0026a220342ccacbdb4f8a587a93d3703002003200041c8026a10ad01450440200020002d00b8023a00c8020b200041003b01d002200041d8026a220242cfacbdb4f8a587a93d370300200141286a1011220320022903001075200328020c200341106a28020047044010000b0240200328020022072003280204220810042205450440410021040c010b410021042001410036022020014200370318200141186a200510532007200820012802182202200128021c220620026b1005417f47044020002001200241016a20062002417f736a10661084013b01e002200521040b2002450d002001200236021c0b200328020c22020440200320023602100b2004450440200020002f01d0023b01e0020b41002102200041003602e802200041f0026a220442ceacbdb4f8a587a93d370300200141286a1011220320042903001075200328020c200341106a28020047044010000b0240200328020022072003280204220810042205450d002001410036022020014200370318200141186a200510532007200820012802182204200128021c220620046b1005417f47044020002001200441016a20062004417f736a10661087013602f802200521020b2004450d002001200436021c0b200328020c22040440200320043602100b2002450440200020002802e8023602f8020b200042003703800320004188036a220242c8acbdb4f8a587a93d370300200141286a1011220320022903001075200328020c200341106a28020047044010000b0240200328020022072003280204220810042205450440410021040c010b410021042001410036022020014200370318200141186a200510532007200820012802182202200128021c220620026b1005417f47044020002001200241016a20062002417f736a106610890137039003200521040b2002450d002001200236021c0b200328020c22020440200320023602100b20044504402000200029038003370390030b410021022000410036029803200041a0036a220442e2e780dbeae4fcabe100370300200141286a1011220320042903001075200328020c200341106a28020047044010000b0240200328020022072003280204220810042205450d002001410036022020014200370318200141186a200510532007200820012802182204200128021c220620046b1005417f47044020002001200441016a20062004417f736a106610723602a803200521020b2004450d002001200436021c0b200328020c22040440200320043602100b200245044020002000280298033602a8030b200042003703b003200041b8036a220242b3debf9dbddf9ca832370300200141286a1011220320022903001075200328020c200341106a28020047044010000b0240200328020022072003280204220810042205450440410021040c010b410021042001410036022020014200370318200141186a200510532007200820012802182202200128021c220620026b1005417f47044020002001200241016a20062002417f736a106610683703c003200521040b2002450d002001200236021c0b200328020c22020440200320023602100b2004450440200020002903b0033703c0030b200042003702c80341002102200041e8036a4100360200200041e0036a22074200370200200041d8036a2204429fe6c89bc186c5be1d370300200041d0036a4100360200200141286a1011220320042903001075200328020c200341106a28020047044010000b0240200328020022082003280204220610042205450d002001410036022020014200370318200141186a200510532008200620012802182204200128021c220920046b1005417f4704402001200441016a20092004417f736a10662007108c01200521020b2004450d002001200436021c0b200328020c22040440200320043602100b20024504402007200041c8036a10260b200041f4036a220342003702002000418c046a2202420037020020004180046a2204428cbcadf0bacdb08975370300200020033602f00320004188046a22072002360200200141286a1011220320042903001075200328020c200341106a28020047044010000b0240200328020022082003280204220610042205450440410021040c010b410021042001410036022020014200370318200141186a200510532008200620012802182202200128021c220920026b1005417f4704402001200241016a20092002417f736a10662007108f01200521040b2002450d002001200236021c0b200328020c22020440200320023602100b20044504402007200041f0036a10290b200042003702980441002102200041b8046a4100360200200041b0046a22074200370200200041a8046a220442bd8ce2969cacfba4b07f370300200041a0046a4100360200200141286a1011220320042903001075200328020c200341106a28020047044010000b0240200328020022082003280204220610042205450d002001410036022020014200370318200141186a200510532008200620012802182204200128021c220920046b1005417f4704402001200441016a20092004417f736a10662007109201200521020b2004450d002001200436021c0b200328020c22040440200320043602100b2002450440200720004198046a102d0b41002102200041c0046a41f800107f1094012109200041b8056a2204429fa88ce0a0829ecea47f370300200041c0056a1094012107200141286a1011220320042903001075200328020c200341106a28020047044010000b0240200328020022082003280204220610042205450d002001410036022020014200370318200141186a200510532008200620012802182204200128021c220620046b1005417f4704402001200441016a20062004417f736a10662007109501200521020b2004450d002001200436021c0b200328020c22040440200320043602100b200245044020072009102f0b200041b8066a1098012109200041c8066a220242bcf8d4f484c7a18d807f370300200041d0066a1098012107200141286a1011220320022903001075200328020c200341106a28020047044010000b0240200328020022082003280204220610042205450440410021040c010b410021042001410036022020014200370318200141186a200510532008200620012802182202200128021c220620026b1005417f4704402001200241016a20062002417f736a10662007109901200521040b2002450d002001200236021c0b200328020c22020440200320023602100b20044504402007200910310b200041e4066a22034200370200200041fc066a22024200370200200041f0066a220442eafdbbb690ac81edca00370300200020033602e006200041f8066a22072002360200200141286a1011220320042903001075200328020c200341106a28020047044010000b0240200328020022082003280204220610042205450440410021040c010b410021042001410036022020014200370318200141186a200510532008200620012802182202200128021c220920026b1005417f4704402001200241016a20092002417f736a10662007109c01200521040b2002450d002001200236021c0b200328020c22020440200320023602100b20044504402007200041e0066a10340b20004188076a2209109f011a20004188096a220242d0b4afbcbf988ce0b77f37030020004190096a109f012107200141286a1011220320022903001075200328020c200341106a28020047044010000b0240200328020022082003280204220610042205450440410021040c010b410021042001410036022020014200370318200141186a200510532008200620012802182202200128021c220620026b1005417f4704402001200241016a20062002417f736a1066200710a001200521040b2002450d002001200236021c0b200328020c22020440200320023602100b20044504402007200941800210361a0b41002104200041b00b6a4100360200200041ac0b6a200041a80b6a2202360200200041a00b6a220542f4ffce959b97c9c1d500370300200041980b6a4100360200200041940b6a200041900b6a2207360200200020073602900b20022002360200200141286a1011220320052903001075200328020c200341106a28020047044010000b0240200328020022062003280204220910042208450d002001410036022020014200370318200141186a200810532006200920012802182205200128021c220620056b1005417f4704402001200541016a20062005417f736a1066200210a201200821040b2005450d002001200536021c0b200328020c22050440200320053602100b20044504402002200710380b200041b80b6a220710a6011a200041d00b6a220242affad78bbfdecaa6f300370300200041d80b6a10a6012104200141286a1011220320022903001075200328020c200341106a28020047044010000b0240200328020022062003280204220910042208450440410021050c010b410021052001410036022020014200370318200141186a200810532006200920012802182202200128021c220620026b1005417f4704402001200241016a20062002417f736a1066200410a701200821050b2002450d002001200236021c0b200328020c22020440200320023602100b200545044020042007290300370300200441106a200741106a280200360200200441086a200741086a2903003703000b200141406b240020000b953102087f027e230041c0086b22052400200541c0066a10112201200041d00b6a22022903001074100f200120022903001075200041d80b6a2102200128020c200141106a28020047044010000b2001280204210720012802002106200541c0046a10112104200210a8012108200420054180026a10ae01220310af012004200820032802046a20032802006b100f200541a0026a200241106a280000220836020020054198026a200241086a290000220937030020052002290000220a37039002200541b0026a2009370300200541b8026a2008360200200541086a2009370300200541106a20083602002005200a3703a8022005200a370300200541d0026a2008360200200541c8026a20093703002005200a3703c00202402004200541c0026a41141058220228020c200241106a280200460440200241046a2104200228020021080c010b200241046a2104100020022802002108200228020c2002280210460d0010000b20062007200820042802001006200328020022040440200320043602040b200228020c22030440200220033602100b200128020c22020440200120023602100b200541c0066a10112202200041a00b6a22012903001074100f200220012903001075200041a80b6a2104200228020c200241106a28020047044010000b2002280204210820022802002107200541c0046a10112101200410a40121062001200541c0026a10ae01220310af012001200620032802046a20032802006b100f2001200410a5010240200128020c200141106a280200460440200141046a2104200128020021060c010b200141046a2104100020012802002106200128020c2001280210460d0010000b20072008200620042802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200041a80b6a10a301200041900b6a10a301200541a8026a1011220120004188096a22022903001074100f20012002290300107520004190096a2104200128020c200141106a28020047044010000b200128020421082001280200210720054190026a10112102200410a1012106200220054180026a10ae01220310af012002200620032802046a20032802006b100f200520044180021036220541c0026a200541800210361a200541c0046a200541c0026a41800210361a200541c0066a200541c0046a41800210361a02402002200541c0066a4180021058220228020c200241106a280200460440200241046a2104200228020021060c010b200241046a2104100020022802002106200228020c2002280210460d0010000b20072008200620042802001006200328020022040440200320043602040b200228020c22030440200220033602100b200128020c22020440200120023602100b200541c0066a10112202200041f0066a22012903001074100f200220012903001075200041f8066a2104200228020c200241106a28020047044010000b2002280204210820022802002107200541c0046a101121012004109d0121062001200541c0026a10ae01220310af012001200620032802046a20032802006b100f20012004109e010240200128020c200141106a280200460440200141046a2104200128020021060c010b200141046a2104100020012802002106200128020c2001280210460d0010000b20072008200620042802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a10112202200041c8066a22012903001074100f200220012903001075200041d0066a2104200228020c200241106a28020047044010000b2002280204210820022802002107200541c0046a101121012004109a0121062001200541c0026a10ae01220310af012001200620032802046a20032802006b100f20012004109b010240200128020c200141106a280200460440200141046a2104200128020021060c010b200141046a2104100020012802002106200128020c2001280210460d0010000b20072008200620042802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a10112202200041b8056a22012903001074100f200220012903001075200041c0056a2104200228020c200241106a28020047044010000b2002280204210820022802002107200541c0046a10112101200410960121062001200541c0026a10ae01220310af012001200620032802046a20032802006b100f200120041097010240200128020c200141106a280200460440200141046a2104200128020021060c010b200141046a2104100020012802002106200128020c2001280210460d0010000b20072008200620042802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a10112202200041a8046a22012903001074100f200220012903001075200041b0046a2104200228020c200241106a28020047044010000b2002280204210820022802002107200541c0046a1011210120002802b004200041b4046a28020010930121062001200541c0026a10ae01220310af012001200620032802046a20032802006b100f2001200410100240200128020c200141106a280200460440200141046a2104200128020021060c010b200141046a2104100020012802002106200128020c2001280210460d0010000b20072008200620042802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200041b0046a28020022010440200041b4046a20013602000b200028029804220104402000419c046a20013602000b200541c0066a1011220220004180046a22012903001074100f20022001290300107520004188046a2104200228020c200241106a28020047044010000b2002280204210820022802002107200541c0046a10112101200410900121062001200541c0026a10ae01220310af012001200620032802046a20032802006b100f200120041091010240200128020c200141106a280200460440200141046a2104200128020021060c010b200141046a2104100020012802002106200128020c2001280210460d0010000b20072008200620042802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a10112202200041d8036a22012903001074100f200220012903001075200041e0036a2104200228020c200241106a28020047044010000b2002280204210820022802002107200541c0046a101121012004108d0121062001200541c0026a10ae01220310af012001200620032802046a20032802006b100f20012004108e010240200128020c200141106a280200460440200141046a2104200128020021060c010b200141046a2104100020012802002106200128020c2001280210460d0010000b20072008200620042802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200041e0036a28020022010440200041e4036a20013602000b20002802c80322010440200041cc036a20013602000b200541c0046a10112202200041b8036a22012903001074100f200220012903001075200228020c200241106a28020047044010000b2002280204210420022802002108200541c0026a10112101200541d8066a4100360200200541d0066a4200370300200541c8066a4200370300200542003703c006200541c0066a20002903c00310b00120052802c0062107200541c0066a41047210152001200541c0066a10ae01220310af012001200720032802046a20032802006b100f200120002903c00310750240200128020c200141106a280200460440200141046a2107200128020021060c010b200141046a2107100020012802002106200128020c2001280210460d0010000b20082004200620072802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0046a10112202200041a0036a22012903001074100f200220012903001075200228020c200241106a28020047044010000b2002280204210420022802002108200541c0026a10112101200541d8066a4100360200200541d0066a4200370300200541c8066a4200370300200542003703c006200541c0066a20002802a803101920052802c0062107200541c0066a41047210152001200541c0066a10ae01220310af012001200720032802046a20032802006b100f200120002802a803101a0240200128020c200141106a280200460440200141046a2107200128020021060c010b200141046a2107100020012802002106200128020c2001280210460d0010000b20082004200620072802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a1011220220004188036a22012903001074100f200220012903001075200228020c200241106a28020047044010000b2002280204210420022802002108200541c0046a10112101200029039003108a0121072001200541c0026a10ae01220310af012001200720032802046a20032802006b100f2001200029039003108b010240200128020c200141106a280200460440200141046a2107200128020021060c010b200141046a2107100020012802002106200128020c2001280210460d0010000b20082004200620072802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a10112202200041f0026a22012903001074100f200220012903001075200228020c200241106a28020047044010000b2002280204210420022802002108200541c0046a1011210120002802f80210880121072001200541c0026a10ae01220310af012001200720032802046a20032802006b100f200120002802f8021086010240200128020c200141106a280200460440200141046a2107200128020021060c010b200141046a2107100020012802002106200128020c2001280210460d0010000b20082004200620072802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a10112202200041d8026a22012903001074100f200220012903001075200228020c200241106a28020047044010000b2002280204210420022802002108200541c0046a1011210120002f01e00210850121072001200541c0026a10ae01220310af012001200720032802046a20032802006b100f200120002e01e0021086010240200128020c200141106a280200460440200141046a2107200128020021060c010b200141046a2107100020012802002106200128020c2001280210460d0010000b20082004200620072802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200041c0026a200041c8026a10b101200541c0066a1011220220004188026a22012903001074100f20022001290300107520004190026a2104200228020c200241106a28020047044010000b2002280204210820022802002107200541c0046a10112101200410820121062001200541c0026a10ae01220310af012001200620032802046a20032802006b100f200120041083010240200128020c200141106a280200460440200141046a2104200128020021060c010b200141046a2104100020012802002106200128020c2001280210460d0010000b20072008200620042802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a10112202200041c8016a22012903001074100f200220012903001075200041d0016a2104200228020c200241106a28020047044010000b2002280204210820022802002107200541c0046a101121012004107d21062001200541c0026a10ae01220310af012001200620032802046a20032802006b100f20012004107e0240200128020c200141106a280200460440200141046a2104200128020021060c010b200141046a2104100020012802002106200128020c2001280210460d0010000b20072008200620042802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200041a8016a200041b0016a10b101200541c0066a1011220220004190016a22012903001074100f200220012903001075200228020c200241106a28020047044010000b2002280204210420022802002108200541c0046a1011210120002d009801106f21072001200541c0026a10ae01220310af012001200720032802046a20032802006b100f200120002d009801101a0240200128020c200141106a280200460440200141046a2107200128020021060c010b200141046a2107100020012802002106200128020c2001280210460d0010000b20082004200620072802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a10112201200041f0006a22022903001074100f200120022903001075200041f8006a2104200128020c200141106a28020047044010000b2001280204210820012802002107200541c0046a101121022004105221062002200541c0026a10ae01220310af012002200620032802046a20032802006b100f024020022005200410121017220228020c200241106a280200460440200241046a2104200228020021060c010b200241046a2104100020022802002106200228020c2002280210460d0010000b20072008200620042802001006200328020022040440200320043602040b200228020c22030440200220033602100b200128020c22020440200120023602100b200541c0066a10112202200041d0006a22012903001074100f200220012903001075200228020c200241106a28020047044010000b2002280204210420022802002108200541c0046a101121012000290358107421072001200541c0026a10ae01220310af012001200720032802046a20032802006b100f2001200029035810750240200128020c200141106a280200460440200141046a2107200128020021060c010b200141046a2107100020012802002106200128020c2001280210460d0010000b20082004200620072802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a10112202200041386a22012903001074100f200220012903001075200228020c200241106a28020047044010000b2002280204210420022802002108200541c0046a101121012000280240107321072001200541c0026a10ae01220310af012001200720032802046a20032802006b100f20012000280240101a0240200128020c200141106a280200460440200141046a2107200128020021060c010b200141046a2107100020012802002106200128020c2001280210460d0010000b20082004200620072802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a10112202200041206a22012903001074100f200220012903001075200228020c200241106a28020047044010000b2002280204210420022802002108200541c0046a1011210120002f0128107121072001200541c0026a10ae01220310af012001200720032802046a20032802006b100f200120002f0128101a0240200128020c200141106a280200460440200141046a2107200128020021060c010b200141046a2107100020012802002106200128020c2001280210460d0010000b20082004200620072802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0066a1011220220002903081074100f200220002903081075200228020c200241106a28020047044010000b2002280204210420022802002108200541c0046a1011210120002d0010106f21072001200541c0026a10ae01220310af012001200720032802046a20032802006b100f200120002d0010101a0240200128020c200141106a280200460440200141046a2107200128020021060c010b200141046a2107100020012802002106200128020c2001280210460d0010000b20082004200620072802001006200328020022040440200320043602040b200128020c22030440200120033602100b200228020c22010440200220013602100b200541c0086a24000b2601017f02402000280204450d0020002802002d000041c001490d00200010b20121010b20010b800101037f230041106b22012400200010aa0102400240200010ab01450d002000280204450d0020002802002d000041c001490d010b10000b200141086a200010ac01200128020c220041024f044010000b200128020821020340200004402000417f6a210020022d00002103200241016a21020c010b0b200141106a240020030b5801027f230041206b22012400200141186a4100360200200141106a4200370300200141086a42003703002001420037030020012000ad42ff018342001056210020012802002102200041046a1015200141206a240020020b8b0101037f230041106b22012400200010aa0102400240200010ab01450d002000280204450d0020002802002d000041c001490d010b10000b200141086a200010ac01200128020c220041034f044010000b200128020821030340200004402000417f6a210020032d00002002410874722102200341016a21030c010b0b200141106a2400200241ffff03710b5401017f230041206b22012400200141186a4100360200200141106a4200370300200141086a4200370300200142003703002001200041ffff037110192001280200210020014104721015200141206a240020000b860101037f230041106b22012400200010aa0102400240200010ab01450d002000280204450d0020002802002d000041c001490d010b10000b200141086a200010ac01200128020c220041054f044010000b200128020821030340200004402000417f6a210020032d00002002410874722102200341016a21030c010b0b200141106a240020020b4f01017f230041206b22012400200141186a4100360200200141106a4200370300200141086a4200370300200142003703002001200010192001280200210020014104721015200141206a240020000b5001027f230041206b22012400200141186a4100360200200141106a4200370300200141086a4200370300200142003703002001200010b0012001280200210220014104721015200141206a240020020b0a0020002001420010590b1a0020004200370200200041086a4100360200200010b30120000ba40201057f230041206b22022400024002402000280204044020002802002d000041c001490d010b200241086a10761a0c010b200241186a200010ac01200010b40121030240024002400240200228021822000440200228021c220520034f0d010b41002100200241106a410036020020024200370308410021050c010b200241106a4100360200200242003703082000200520032003417f461b22046a21052004410a4b0d010b200220044101743a0008200241086a41017221030c010b200441106a4170712206103a21032002200436020c20022006410172360208200220033602100b03402000200546450440200320002d00003a0000200341016a2103200041016a21000c010b0b200341003a00000b2001200241086a10b501200241206a24000b0e0020012000106e4100473a00000b4401027f230041f00b6b220224002000106d410247044010000b2002200041011067200210b60121002002106b21032002200020011100002003106c200241f00b6a24000b7b01027f230041900c6b220224002000106a200241086a106b2103200241086a20011101002100200241f80b6a10112201200010b701100f20012000108601200128020c200141106a28020047044010000b200128020020012802041008200128020c22000440200120003602100b2003106c200241900c6a24000b180020004200370200200041086a4100360200200010761a0b2801017f230041206b22022400200241086a200041001067200241086a20011077200241206a24000b5001017f230041206b22012400200141186a4100360200200141106a4200370300200141086a4200370300200142003703002001200010b8012001280200210020014104721015200141206a240020000b6e01027f230041406a220224002000410110162100200241386a4100360200200241306a4200370300200241286a420037030020024200370320200241206a200241106a200110121014210320002002280220100f200020022001101210171a200341046a1015200241406b24000be10201027f02402001450d00200041003a0000200020016a2203417f6a41003a000020014103490d00200041003a0002200041003a00012003417d6a41003a00002003417e6a41003a000020014107490d00200041003a00032003417c6a41003a000020014109490d002000410020006b41037122026a220341003602002003200120026b417c7122026a2201417c6a410036020020024109490d002003410036020820034100360204200141786a4100360200200141746a410036020020024119490d002003410036021820034100360214200341003602102003410036020c200141706a41003602002001416c6a4100360200200141686a4100360200200141646a41003602002002200341047141187222026b2101200220036a2102034020014120490d0120024200370300200241186a4200370300200241106a4200370300200241086a4200370300200241206a2102200141606a21010c000b000b20000b1900200010761a2000410c6a10761a200041186a10761a20000b5601017f230041206b22022400200241086a200041001067200241086a2001107c200241086a200041011067200241086a2001410c6a1077200241086a200041021067200241086a200141186a1077200241206a24000b7a01027f230041406a22012400200141186a4100360200200141106a4200370300200141086a4200370300200142003703002001410010132202200010b8012002200141306a2000410c6a10121014200141206a200041186a1012101441011013210020012802002102200041046a1015200141406b240020020ba30101047f230041e0006b220224002000410310162100200241d8006a4100360200200241d0006a4200370300200241c8006a420037030020024200370340200241406b200110b801200241406b200241306a2001410c6a220310121014200241206a200141186a220410121014210520002002280240100f20002001107e2000200241106a20031012101720022004101210171a200541046a1015200241e0006a24000b3902017f017e230041106b220124002001200010b90120012903002102200141106a2400420020024201837d200242018885a74110744110750b6202027f017e230041206b22012400200141186a4100360200200141106a4200370300200141086a42003703002001420037030020012000ad42308622034230872003423f8710ba01210020012802002102200041046a1015200141206a240020020b1301017e20002001ac22022002423f8710bb010b3302017f017e230041106b220124002001200010b90120012903002102200141106a2400420020024201837d200242018885a70b5201027f230041206b22012400200141186a4100360200200141106a4200370300200141086a4200370300200142003703002001200010bc01210020012802002102200041046a1015200141206a240020020b4202017f027e230041106b220124002001200010b901200141086a290300210320012903002102200141106a2400420020024201837d2003423f86200242018884850b5701037f230041206b22012400200141186a4100360200200141106a4200370300200141086a420037030020014200370300200120002000423f8710ba01210220012802002103200241046a1015200141206a240020030b0e00200020012001423f8710bb010bb10201047f230041d0006b22022400024002402000280204450d0020002802002d000041c001490d002000106d21032001280208200128020022046b4101752003490440200120022003200128020420046b410175200141086a10bd01220310be01200310bf010b200241286a200010c001200241186a200010c101200141086a21050340200228022c200228021c46044020022802302002280220460d030b2002200241286a10c2012002107021030240200128020422002001280208490440200020033b01002001200041026a3602040c010b200241386a2001200020012802006b410175220041016a104f2000200510bd0121002002280240220420033b01002002200441026a3602402001200010be01200010bf010b200241286a10c3010c000b000b10000b200241d0006a24000b9c0101037f230041206b22012400200141186a4100360200200141106a4200370300200141086a420037030020014200370300024020002802002000280204460440200110c4010c010b200141001013210220002802042103200028020021000340200020034604402002410110131a05200220002f01001019200041026a21000c010b0b0b2001280200210020014104721015200141206a240020000b4301017f2000200128020420012802006b410175101621022001280204210020012802002101034020002001470440200220012f0100101a200141026a21010c010b0b0be20201057f23004190016b22022400024002402000280204450d0020002802002d000041c001490d00200241c8006a200010c001200241386a200010c101200241146a21040340200228024c200228023c46044020022802502002280240460d030b200241206a200241c8006a10c201200241086a10762100200410762105200241206a10c501410247044010000b20024180016a10762103200241e8006a200241206a41001067200241e8006a200310772000200310b501200241d8006a10762103200241e8006a200241206a41011067200241e8006a200310772005200310b5012001200241e8006a2000103d22062802004504404128103a22032002290308370210200341186a200241106a280200360200200010b301200341246a200441086a2802003602002003411c6a2004290200370200200510b3012001200228026820062003103f0b200241c8006a10c3010c000b000b10000b20024190016a24000bd00101047f230041e0006b22012400200141206a4100360200200141186a4200370300200141106a42003703002001420037030802402000280208450440200141086a10c4010c010b200041046a2103200141086a410010132102200141346a2104200028020021000340200020034604402002410110131a05200141286a200041106a104b200241001013200141d0006a200141286a10121014200141406b200410121014410110131a2000102a21000c010b0b0b20012802082100200141086a4104721015200141e0006a240020000b6101027f230041206b220224002000200128020810162103200141046a210020012802002101034020002001460440200241206a240005200341021016200241106a200141106a1012101720022001411c6a101210171a2001102a21010c010b0b0bce0101037f230041206b22022400024002402000280204044020002802002d000041c001490d010b20024100360208200242003703000c010b200241186a200010ac0120022802182103200241106a200010ac0120022802102104200010b40121002002410036020820024200370300200020046a20036b2200450d0020022000104520004101480d002002200228020420032000103620006a3602040b2001280200044020014100360208200142003702000b2001200228020036020020012002290204370204200241206a24000b5301017f230041206b22022400200241186a4100360200200241106a4200370300200241086a420037030020024200370300200220002001100e210020022802002101200041046a1015200241206a240020010b2c01037f200041f8006a21022000210103402001107621032001410c6a21012003410c6a2002470d000b20000b6101037f230041306b22022400200010c501410a47044010000b03402003410a460440200241306a240005200241206a10762104200241086a200020031067200241086a200410772001200410b5012001410c6a2101200341016a21030c010b0b0b800101037f230041306b22012400200141186a4100360200200141106a4200370300200141086a42003703002001420037030020014100101321030340200241f800464504402003200141206a200020026a101210141a2002410c6a21020c010b0b200341011013210220012802002103200241046a1015200141306a240020030b4401027f230041106b220224002000410a10162103410021000340200041f800460440200241106a24000520032002200020016a101210171a2000410c6a21000c010b0b0b1000200010761a2000410036020c20000b5d01027f230041306b22022400200010c501410247044010000b200241206a10762103200241086a200041001067200241086a200310772001200310b501200241086a2000410110672001200241086a10870136020c200241306a24000b7301027f230041406a22012400200141286a4100360200200141206a4200370300200141186a4200370300200142003703102001200010322100200141106a41001013200141306a200010121014200028020c10bc0141011013210020012802102102200041046a1015200141406b240020020b2a01017f230041106b220224002000410210162002200110121017200128020c108601200241106a24000bd70101047f230041d0006b22022400024002402000280204450d0020002802002d000041c001490d00200241406b200010c001200241306a200010c101200241106a210403402002280244200228023446044020022802482002280238460d030b200241186a200241406b10c201200241186a200241086a1076220010772001200241cc006a2000103d2205280200450440411c103a22032002290308370210200341186a2004280200360200200010b3012001200228024c20052003103f0b200241406b10c3010c000b000b10000b200241d0006a24000b9e0101037f230041306b22012400200141186a4100360200200141106a4200370300200141086a42003703002001420037030002402000280208450440200110c4010c010b200041046a21032001410010132102200028020021000340200020034604402002410110131a052002200141206a200041106a101210141a2000102a21000c010b0b0b2001280200210020014104721015200141306a240020000b4f01027f230041106b220224002000200128020810162103200141046a210020012802002101034020002001460440200241106a24000520032002200141106a101210171a2001102a21010c010b0b0b2601017f0340200141800246450440200020016a41003a0000200141016a21010c010b0b20000b990101027f23004190046b22022400200010aa0120024188046a200010ac01200228028c042103024002402000280204450d0020034180024b0d0020002802002d000041c001490d010b10000b20024188026a109f0120034180022003418002491b22006b4180026a200228028804200010361a200241086a20024188026a41800210361a2001200241086a41800210361a20024190046a24000bc00101037f230041a0086b2201240020014198026a410036020020014190026a420037030020014188026a42003703002001420037038002200120004180021036220041a0026a200041800210361a200041a0046a200041a0026a41800210361a200041a0066a200041a0046a41800210361a41012103024003402002418002460d01200041a0066a20026a2101200241016a210220012d0000450d000b41830221030b200020033602800220004180026a4104721015200041a0086a240020030bec0101037f230041d0006b22022400024002402000280204450d0020002802002d000041c001490d00200241406b200010c001200241306a200010c101200241106a210403402002280244200228023446044020022802482002280238460d030b200241186a200241406b10c201200241186a200241086a1076220310774114103a2200410036020020002002290308370208200041106a2004280200360200200310b30120002001360204200128020021032001200036020020002003360200200320003602042001200128020841016a360208200241406b10c3010c000b000b10000b200241d0006a24000b4d01037f02402000280208450d00200028020422012802002202200028020022032802043602042000410036020820032802042002360200034020002001460d01200128020421010c000b000b0b9d0101037f230041306b22012400200141186a4100360200200141106a4200370300200141086a42003703002001420037030002402000280208450440200110c4010c010b200041046a2102200141001013210303402002280200220220004604402003410110131a052003200141206a200241086a101210141a200241046a21020c010b0b0b2001280200210220014104721015200141306a240020020b4e01027f230041106b22032400200141046a210220002001280208101621000340200228020022022001460440200341106a24000520002003200241086a101210171a200241046a21020c010b0b0b2501017f03402001411446450440200020016a41003a0000200141016a21010c010b0b20000bbe0102027f027e230041406a22022400200010aa01200241386a200010ac01200228023c2103024002402000280204450d00200341144b0d0020002802002d000041c001490d010b10000b200241206a10a6012003411420034114491b22006b41146a2002280238200010361a200241186a200241306a2802002200360200200241106a200241286a2903002204370300200220022903202205370308200141106a2000360000200141086a200437000020012005370000200241406b24000b850202037f027e23004180016b22012400200141306a4100360200200141286a4200370300200141206a4200370300200141086a200041086a2900002204370300200141106a200041106a280000220236020020014200370318200120002900002205370300200141406b2004370300200141c8006a2002360200200141d8006a2004370300200141e0006a20023602002001200537033820012005370350200141f8006a2002360200200141f0006a200437030020012005370368410121020240034020034114460d01200141e8006a20036a2100200341016a210320002d0000450d000b411521020b20012002360218200141186a410472101520014180016a240020020b750020004200370210200042ffffffff0f370208200020023602042000200136020002402003410871450d00200010c90120024f0d002003410471044010000c010b200042003702000b02402003411071450d00200010c90120024d0d0020034104710440100020000f0b200042003702000b20000b4101017f200028020445044010000b0240200028020022012d0000418101470d00200028020441014d047f100020002802000520010b2c00014100480d0010000b0b990101037f200028020445044041000f0b200010aa01200028020022022c0000220141004e044020014100470f0b027f4101200141807f460d001a200141ff0171220341b7014d0440200028020441014d047f100020002802000520020b2d00014100470f0b4100200341bf014b0d001a2000280204200141ff017141ca7e6a22014d047f100020002802000520020b20016a2d00004100470b0bd60101047f200110b4012204200128020422024b04401000200128020421020b200128020021052000027f02400240200204404100210120052c00002203417f4a0d01027f200341ff0171220141bf014d04404100200341ff017141b801490d011a200141c97e6a0c010b4100200341ff017141f801490d001a200141897e6a0b41016a21010c010b4101210120050d000c010b41002103200120046a20024b0d0020022001490d00410020022004490d011a200120056a2103200220016b20042004417f461b0c010b41000b360204200020033602000bc20101057f230041406a22022400200241286a1011220320002903001075200328020c200341106a28020047044010000b02402003280200220020032802042205100422064504400c010b2002410036022020024200370318200241186a200610532000200520022802182200200228021c220520006b1005417f47044020012002200041016a20052000417f736a106610b6013a0000200621040b2000450d002002200036021c0b200328020c22000440200320003602100b200241406b240020040b30002000410036020820004200370200200041011045200028020441fe013a00002000200028020441016a36020420000b6101037f200028020c200041106a28020047044010000b200028020422022001280204200128020022036b22016a220420002802084b047f20002004105720002802040520020b20002802006a2003200110361a2000200028020420016a3602040b0b0020002001420010561a0b8e0201067f230041406a22042400200441286a1011220220002903001074100f200220002903001075200228020c200241106a28020047044010000b2002280204210620022802002107200441106a1011210020012d000010b70121052000200410ae01220310af012000200520032802046a20032802006b100f200020012c00001086010240200028020c200041106a280200460440200041046a2101200028020021050c010b200041046a2101100020002802002105200028020c2000280210460d0010000b20072006200520012802001006200328020022010440200320013602040b200028020c22030440200020033602100b200228020c22000440200220003602100b200441406b24000b820101047f230041106b2201240002402000280204450d0020002802002d000041c001490d00200141086a200010cd01200128020c210003402000450d0120014100200128020822032003200010cb0122046a20034520002004497222031b3602084100200020046b20031b2100200241016a21020c000b000b200141106a240020020b2201017f03402001410c470440200020016a4100360200200141046a21010c010b0b0b800301037f200028020445044041000f0b200010aa0141012102024020002802002c00002201417f4a0d00200141ff0171220341b7014d0440200341807f6a0f0b02400240200141ff0171220141bf014d0440024020002802042201200341c97e6a22024d047f100020002802040520010b4102490d0020002802002d00010d0010000b200241054f044010000b20002802002d000145044010000b4100210241b7012101034020012003460440200241384f0d030c0405200028020020016a41ca7e6a2d00002002410874722102200141016a21010c010b000b000b200141f7014d0440200341c07e6a0f0b024020002802042201200341897e6a22024d047f100020002802040520010b4102490d0020002802002d00010d0010000b200241054f044010000b20002802002d000145044010000b4100210241f701210103402001200346044020024138490d0305200028020020016a418a7e6a2d00002002410874722102200141016a21010c010b0b0b200241ff7d490d010b10000b20020b5c00024020002d0000410171450440200041003b01000c010b200028020841003a00002000410036020420002d0000410171450d00200041003602000b20002001290200370200200041086a200141086a280200360200200110b3010b3902017f017e230041106b220124002001200010b90120012903002102200141106a2400420020024201837d200242018885a74118744118750b6202027f017e230041206b22012400200141186a4100360200200141106a4200370300200141086a42003703002001420037030020012000ad42388622034238872003423f8710ba01210020012802002102200041046a1015200141206a240020020b2701017f230041106b220224002000410010132002200110121014410110131a200241106a24000ba10102027f027e230041106b22022400200110aa0102400240200110ab01450d002001280204450d0020012802002d000041c001490d010b10000b200241086a200110ac01200228020c220141114f044010000b20022802082103034020010440200542088620044238888421052001417f6a210120033100002004420886842104200341016a21030c010b0b2000200437030020002005370308200241106a24000b2301017e20002002423f87220320014201868520024201862001423f888420038510560b2301017e20002002423f87220320014201868520024201862001423f888420038510590b1301017e20002001ac22022002423f8710ba010b4c01017f2000410036020c200041106a2003360200200104402001104d21040b200020043602002000200420024101746a22023602082000200420014101746a36020c2000200236020420000b870101037f200120012802042000280204200028020022046b22036b2202360204200341004a044020022004200310361a200128020421020b200028020021032000200236020020012003360204200028020421022000200128020836020420012002360208200028020821022000200128020c3602082001200236020c200120012802043602000b2b01027f200028020821012000280204210203402001200247044020002001417e6a22013602080c010b0b0b0b0020002001410110c6010b0b0020002001410010c6010b170020002001280204200141086a280200411c10a9011a0bb70102057f017e230041106b22032400200041046a210102402000280200220204402001280200220504402005200041086a2802006a21040b20002004360204200041086a2002360200200341086a200141002004200210cb0110cc0120002003290308220637020420004100200028020022012006422088a76b2202200220014b1b3602000c010b200020012802002201047f2001200041086a2802006a0541000b360204200041086a41003602000b200341106a24000b3901017f027f200041186a28020022010440200041086a280200200041146a280200200110550c010b20000b2201200128020041016a3602000b220002402000280204044020002802002d000041bf014b0d010b10000b200010b2010be70101037f230041106b2204240020004200370200200041086a410036020020012802042103024002402002450440200321020c010b410021022003450d002003210220012802002d000041c001490d00200441086a200110cd0120004100200428020c220120042802082202200110cb0122032003417f461b20024520012003497222031b220536020820004100200220031b3602042000200120056b3602000c010b20012802002103200128020421012000410036020020004100200220016b20034520022001497222021b36020820004100200120036a20021b3602040b200441106a24000b3501017f230041106b220041908c0436020c41800c200028020c41076a417871220036020041840c200036020041880c3f003602000b10002002044020002001200210361a0b0b3001017f200028020445044041000f0b4101210120002802002c0000417f4c047f200010ca01200010b4016a0520010b0b5b00027f027f41002000280204450d001a410020002802002c0000417f4a0d011a20002802002d0000220041bf014d04404100200041b801490d011a200041c97e6a0c010b4100200041f801490d001a200041897e6a0b41016a0b0b2901017f230041206b22022400200241086a20002001411410a90110c9012100200241206a240020000b5b01027f2000027f0240200128020022054504400c010b200220036a200128020422014b0d0020012002490d00410020012003490d011a200220056a2104200120026b20032003417f461b0c010b41000b360204200020043602000b2401017f200110b401220220012802044b044010000b20002001200110ca01200210cc010b2f002000200210cf01200028020020002802046a2001200210361a2000200028020420026a3602042000200310d0010b1b00200028020420016a220120002802084b04402000200110570b0b830201047f02402001450d00034020002802102202200028020c460d01200241786a28020020014904401000200028021021020b200241786a2203200328020020016b220136020020010d012000200336021020004101200028020422032002417c6a28020022016b22021054220441016a20024138491b220520036a10d101200120002802006a220320056a2003200210490240200241374d0440200028020020016a200241406a3a00000c010b200441f7016a220341ff014d0440200028020020016a20033a00002000280200200120046a6a210103402002450d02200120023a0000200241087621022001417f6a21010c000b000b10000b410121010c000b000b0b0f00200020011057200020013602040b26002000410110cf01200028020020002802046a20013a00002000200028020441016a3602040b6001027f20011054220241b7016a22034180024e044010000b2000200341ff017110d2012000200028020420026a10d101200028020420002802006a417f6a2100034020010440200020013a0000200141087621012000417f6a21000c010b0b0b0bfa0301004180080bf203746f70696331006461746131006a735f636f6e7472616374006576656e740073657455696e7433324576740073657455696e743136457674007472616e7366657200696e69740073657455696e74380067657455696e74380073657455696e7431360067657455696e7431360073657455696e7433320067657455696e7433320073657455696e7436340067657455696e74363400736574537472696e6700676574537472696e6700736574426f6f6c00676574426f6f6c00736574436861720067657443686172007365744d657373616765006765744d657373616765007365744d794d657373616765006765744d794d65737361676500736574496e743800676574496e743800736574496e74313600676574496e74313600736574496e74333200676574496e74333200736574496e74363400676574496e74363400736574566563746f7200676574566563746f72007365744d6170006765744d617000746573744d756c7469506172616d730073657442797465730067657442797465730073657441727261790067657441727261790073657450616972006765745061697200736574536574006765745365740073657446697865644861736800676574466978656448617368007365744c697374006765744c69737400736574416464726573730067657441646472657373' +abi = [{"constant":false,"input":[{"name":"input","type":"string[10]"}],"name":"setArray","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getUint32","output":"uint32","type":"Action"},{"constant":false,"input":[{"name":"input","type":"int64"}],"name":"setInt64","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getInt64","output":"int64","type":"Action"},{"constant":false,"input":[{"name":"input","type":"pair"}],"name":"setPair","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getPair","output":"pair","type":"Action"},{"anonymous":false,"input":[{"name":"topic","type":"string"},{"name":"arg1","type":"string"}],"name":"transfer","topic":1,"type":"Event"},{"anonymous":false,"input":[{"name":"topic","type":"string"},{"name":"arg1","type":"string"},{"name":"arg2","type":"uint16"}],"name":"setUint16Evt","topic":1,"type":"Event"},{"constant":false,"input":[{"name":"addr","type":"FixedHash<20>"}],"name":"setAddress","output":"void","type":"Action"},{"anonymous":false,"input":[{"name":"topic1","type":"string"},{"name":"topic2","type":"uint32"},{"name":"arg1","type":"string"},{"name":"arg2","type":"uint32"},{"name":"arg3","type":"uint32"}],"name":"setUint32Evt","topic":2,"type":"Event"},{"constant":false,"input":[],"name":"init","output":"void","type":"Action"},{"constant":false,"input":[{"name":"input","type":"uint8"}],"name":"setUint8","output":"void","type":"Action"},{"baseclass":[],"fields":[{"name":"head","type":"string"}],"name":"message","type":"struct"},{"constant":false,"input":[{"name":"msg","type":"message"}],"name":"setMessage","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getUint8","output":"uint8","type":"Action"},{"constant":false,"input":[{"name":"input","type":"uint16"}],"name":"setUint16","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getUint16","output":"uint16","type":"Action"},{"constant":false,"input":[{"name":"input","type":"uint32"}],"name":"setUint32","output":"void","type":"Action"},{"constant":false,"input":[{"name":"input","type":"uint64"}],"name":"setUint64","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getUint64","output":"uint64","type":"Action"},{"constant":false,"input":[{"name":"input","type":"string"}],"name":"setString","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getString","output":"string","type":"Action"},{"constant":false,"input":[{"name":"input","type":"bool"}],"name":"setBool","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getBool","output":"bool","type":"Action"},{"constant":false,"input":[{"name":"input","type":"int8"}],"name":"setChar","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getChar","output":"int8","type":"Action"},{"constant":true,"input":[],"name":"getMessage","output":"message","type":"Action"},{"baseclass":["message"],"fields":[{"name":"body","type":"string"},{"name":"end","type":"string"}],"name":"my_message","type":"struct"},{"constant":false,"input":[{"name":"msg","type":"my_message"}],"name":"setMyMessage","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getMyMessage","output":"my_message","type":"Action"},{"constant":false,"input":[{"name":"input","type":"int8"}],"name":"setInt8","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getSet","output":"set","type":"Action"},{"constant":true,"input":[],"name":"getInt8","output":"int8","type":"Action"},{"constant":false,"input":[{"name":"input","type":"int16"}],"name":"setInt16","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getInt16","output":"int16","type":"Action"},{"constant":false,"input":[{"name":"input","type":"int32"}],"name":"setInt32","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getInt32","output":"int32","type":"Action"},{"constant":false,"input":[{"name":"vec","type":"uint16[]"}],"name":"setVector","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getVector","output":"uint16[]","type":"Action"},{"constant":false,"input":[{"name":"input","type":"map"}],"name":"setMap","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getMap","output":"map","type":"Action"},{"constant":false,"input":[{"name":"msg","type":"message"},{"name":"input1","type":"int32"},{"name":"input2","type":"bool"}],"name":"testMultiParams","output":"void","type":"Action"},{"constant":false,"input":[{"name":"input","type":"uint8[]"}],"name":"setBytes","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getBytes","output":"uint8[]","type":"Action"},{"constant":true,"input":[],"name":"getArray","output":"string[10]","type":"Action"},{"constant":false,"input":[{"name":"input","type":"set"}],"name":"setSet","output":"void","type":"Action"},{"constant":false,"input":[{"name":"input","type":"FixedHash<256>"}],"name":"setFixedHash","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getFixedHash","output":"FixedHash<256>","type":"Action"},{"constant":false,"input":[{"name":"input","type":"list"}],"name":"setList","output":"void","type":"Action"},{"constant":true,"input":[],"name":"getList","output":"list","type":"Action"},{"constant":true,"input":[],"name":"getAddress","output":"FixedHash<20>","type":"Action"}] + +# Instantiate and deploy contract +Payable = platon.wasmcontract(abi=abi, bytecode=bytecode,vmtype=1) + +tx_hash = Payable.constructor().transact( + { + 'from':from_address, + 'gas':1500000, + } +) +# Wait for the transaction to be mined, and get the transaction receipt +tx_receipt = platon.waitForTransactionReceipt(tx_hash) + +# Create the contract instance with the newly-deployed address +greeter = platon.wasmcontract(address=tx_receipt.contractAddress, abi=abi,vmtype=1) + +tx_hash = greeter.functions.setUint8(100).transact( + { + 'from': from_address, + 'gas': 1500000, + } +) + +tx_receipt = platon.waitForTransactionReceipt(tx_hash) +print(tx_receipt) + +topic_param = greeter.events.transfer().processReceipt(tx_receipt) +print(topic_param) +# (AttributeDict({'args': AttributeDict({'topic': b'\x88\x0e\x90\x9d_6m\xaddf\xaeX\x10\x12R\x13G*9\x12UL_\xcc?\xa4G\x1b\xe43/\xcc', 'arg1': 'event'}), 'event': 'transfer', 'logIndex': 0, 'transactionIndex': 0, 'transactionHash': HexBytes('0x1912cb72debbae05e164be6a36941ddf90a0d9cfc9a5c39845f55e0b95430330'), 'address': 'lax1nnzpqm57emppmauusd0rwyr37xv7ww3dnj4rwk', 'blockHash': HexBytes('0x4f6c2dbbe4aafd13bae6b3b90b698bf40f53960e296faf112eda70a8e3266c55'), 'blockNumber': 779304}),) + +# tx_hash = greeter.functions.setUint16(100).transact( +# { +# 'from': from_address, +# 'gas': 1500000, +# } +# ) +# +# tx_receipt = platon.waitForTransactionReceipt(tx_hash) +# print(tx_receipt) +# +# topic_param = greeter.events.setUint16Evt().processReceipt(tx_receipt) +# print(topic_param) +# (AttributeDict({'args': AttributeDict({'topic': b"\xb1\xb4Hd\x86\xa6\xf3\xa06\x0b&lhjx\x8f\x1d_\x15\xf0\xfePkL\x1e'\xe0\xc1^\xff\xe6\xe8", 'arg1': 'data1', 'arg2': 100}), 'event': 'setUint16Evt', 'logIndex': 0, 'transactionIndex': 0, 'transactionHash': HexBytes('0x51501b4c86fffb5b994777fb69cd16138259587bcb0656f8d13c511b9166c07d'), 'address': 'lax1d7565uyrcpmed06zrk2vcdewz4d0059jj40swe', 'blockHash': HexBytes('0xb785a9cd25da636d3b6b0545a228aeecd66ae52b926885fd5c37c1fa5d81e133'), 'blockNumber': 781020}),) +# tx_hash = greeter.functions.setUint32(1000).transact( +# { +# 'from': from_address, +# 'gas': 1500000, +# } +# ) +# +# tx_receipt = platon.waitForTransactionReceipt(tx_hash) +# print(tx_receipt) +# +# topic_param = greeter.events.setUint32Evt().processReceipt(tx_receipt) +# print(topic_param) +# (AttributeDict({'args': AttributeDict({'topic1': b"\xb1\xb4Hd\x86\xa6\xf3\xa06\x0b&lhjx\x8f\x1d_\x15\xf0\xfePkL\x1e'\xe0\xc1^\xff\xe6\xe8", 'topic2': 1000, 'arg1': 'data1', 'arg2': 1000, 'arg3': 1000}), 'event': 'setUint32Evt', 'logIndex': 0, 'transactionIndex': 0, 'transactionHash': HexBytes('0xec039b16047b0bd7b0612bbe44811b5a107b42cfd4dd90b96bd31b1b8fb42478'), 'address': 'lax1v9zkt50lk8vtcc823nq3cm26f5zmnqt4nagwxx', 'blockHash': HexBytes('0x1f66ce0b8c7723be2979fda99160cc8163c6982781ff14f7da357ee6bbdef327'), 'blockNumber': 781613}),) \ No newline at end of file