eth-erc721

ERC-721 'NFT' token interface with example developer badge token contract
Log | Files | Refs | LICENSE

commit 185d0e6795f3f560ec194ac782766e7a4c453c0e
parent 5edeecb1fcb48d66422d6ce557a5a785c5979907
Author: nolash <dev@holbrook.no>
Date:   Sat,  8 May 2021 11:53:17 +0200

Add tokenuri interface, tokenid to sha256 scheme url in badge contract

Diffstat:
Mpython/eth_badge/data/BadgeToken.bin | 4++--
Mpython/eth_badge/data/BadgeToken.json | 2+-
Mpython/eth_erc721/erc721.py | 20++++++++++++++++++++
Mpython/tests/test_app.py | 11+++++++++++
Msolidity/BadgeToken.sol | 41+++++++++++++++++++++++++++++++++++++++++
5 files changed, 75 insertions(+), 3 deletions(-)

diff --git a/python/eth_badge/data/BadgeToken.bin b/python/eth_badge/data/BadgeToken.bin @@ -1 +1 @@ -60806040523480156200001157600080fd5b50604051620028113803806200281183398181016040528101906200003791906200022c565b82600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555081600c9080519060200190620000d0929190620000f3565b5080600d9080519060200190620000e9929190620000f3565b5050505062000472565b82805462000101906200037d565b90600052602060002090601f01602090048101928262000125576000855562000171565b82601f106200014057805160ff191683800117855562000171565b8280016001018555821562000171579182015b828111156200017057825182559160200191906001019062000153565b5b50905062000180919062000184565b5090565b5b808211156200019f57600081600090555060010162000185565b5090565b6000620001ba620001b484620002dd565b620002b4565b905082815260208101848484011115620001d357600080fd5b620001e084828562000347565b509392505050565b600081519050620001f98162000458565b92915050565b600082601f8301126200021157600080fd5b815162000223848260208601620001a3565b91505092915050565b6000806000606084860312156200024257600080fd5b60006200025286828701620001e8565b935050602084015167ffffffffffffffff8111156200027057600080fd5b6200027e86828701620001ff565b925050604084015167ffffffffffffffff8111156200029c57600080fd5b620002aa86828701620001ff565b9150509250925092565b6000620002c0620002d3565b9050620002ce8282620003b3565b919050565b6000604051905090565b600067ffffffffffffffff821115620002fb57620002fa62000418565b5b620003068262000447565b9050602081019050919050565b6000620003208262000327565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60005b83811015620003675780820151818401526020810190506200034a565b8381111562000377576000848401525b50505050565b600060028204905060018216806200039657607f821691505b60208210811415620003ad57620003ac620003e9565b5b50919050565b620003be8262000447565b810181811067ffffffffffffffff82111715620003e057620003df62000418565b5b80604052505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b620004638162000313565b81146200046f57600080fd5b50565b61238f80620004826000396000f3fe60806040526004361061013c576000357c0100000000000000000000000000000000000000000000000000000000900480636352211e116100bd578063a22cb46511610081578063a22cb46514610417578063b88d4fde14610440578063e985e9c51461045c578063f1b0aa1514610499578063f2fde38b146104d65761013c565b80636352211e1461031c57806370a08231146103595780638da5cb5b1461039657806392088cf6146103c157806395d89b41146103ec5761013c565b806323b872dd1161010457806323b872dd1461022d5780632f745c591461024957806342842e0e14610286578063449a52f8146102a25780634f6ccce7146102df5761013c565b806301ffc9a71461014157806306fdde031461017e578063081812fc146101a9578063095ea7b3146101e657806318160ddd14610202575b600080fd5b34801561014d57600080fd5b5061016860048036038101906101639190611e6e565b610513565b6040516101759190611f50565b60405180910390f35b34801561018a57600080fd5b506101936106be565b6040516101a09190611f86565b60405180910390f35b3480156101b557600080fd5b506101d060048036038101906101cb9190611e97565b61074c565b6040516101dd9190611f35565b60405180910390f35b61020060048036038101906101fb9190611e32565b610789565b005b34801561020e57600080fd5b506102176108a5565b6040516102249190611fa8565b60405180910390f35b61024760048036038101906102429190611d2c565b6108b2565b005b34801561025557600080fd5b50610270600480360381019061026b9190611e32565b610921565b60405161027d9190611fa8565b60405180910390f35b6102a0600480360381019061029b9190611d2c565b6109f8565b005b3480156102ae57600080fd5b506102c960048036038101906102c49190611e32565b610a67565b6040516102d69190611f50565b60405180910390f35b3480156102eb57600080fd5b5061030660048036038101906103019190611e97565b610d29565b6040516103139190611fa8565b60405180910390f35b34801561032857600080fd5b50610343600480360381019061033e9190611e97565b610d77565b6040516103509190611f35565b60405180910390f35b34801561036557600080fd5b50610380600480360381019061037b9190611cc7565b610db4565b60405161038d9190611fa8565b60405180910390f35b3480156103a257600080fd5b506103ab610dfd565b6040516103b89190611f35565b60405180910390f35b3480156103cd57600080fd5b506103d6610e21565b6040516103e39190611f35565b60405180910390f35b3480156103f857600080fd5b50610401610e47565b60405161040e9190611f86565b60405180910390f35b34801561042357600080fd5b5061043e60048036038101906104399190611df6565b610ed5565b005b61045a60048036038101906104559190611d7b565b611178565b005b34801561046857600080fd5b50610483600480360381019061047e9190611cf0565b6112c2565b6040516104909190611f50565b60405180910390f35b3480156104a557600080fd5b506104c060048036038101906104bb9190611e97565b61135a565b6040516104cd9190611fa8565b60405180910390f35b3480156104e257600080fd5b506104fd60048036038101906104f89190611cc7565b6113c0565b60405161050a9190611f50565b60405180910390f35b60006380ac58cd7c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561056857600190506106b9565b635b5e139f7c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614156105bb57600190506106b9565b63780e9d637c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561060e57600190506106b9565b63449a52f87c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561066157600190506106b9565b6301ffc9a77c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614156106b457600190506106b9565b600090505b919050565b600c80546106cb90612153565b80601f01602080910402602001604051908101604052809291908181526020018280546106f790612153565b80156107445780601f1061071957610100808354040283529160200191610744565b820191906000526020600020905b81548152906001019060200180831161072757829003601f168201915b505050505081565b60006009600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b3373ffffffffffffffffffffffffffffffffffffffff166005600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146107f457600080fd5b816009600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000600280549050905090565b60606108c0848484846115e6565b818373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a450505050565b6000600860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054821061096e57600080fd5b600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002082815481106109e5577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154905092915050565b6060610a06848484846115e6565b818373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a450505050565b60003373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610ac157600080fd5b600060046000848152602001908152602001600020541480610ae857506000600280549050145b610af157600080fd5b600080600280549050915083905060028190806001815401808255809150506001900390600052602060002001600090919091909150556003439080600181540180825580915050600190039060005260206000200160009091909190915055846005600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508360076000600660008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002080549050815260200190815260200160002081905550600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020849080600181540180825580915050600190039060005260206000200160009091909190915055600860008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000815480929190610cb3906121b6565b91905055508473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fab8530f87dc9b59234c4623bf917212bb2536d647574c8e7e5da92c2ede0c9f886604051610d159190611fa8565b60405180910390a360019250505092915050565b600060028281548110610d65577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600052602060002001549050919050565b60006005600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000600860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600d8054610e5490612153565b80601f0160208091040260200160405190810160405280929190818152602001828054610e8090612153565b8015610ecd5780601f10610ea257610100808354040283529160200191610ecd565b820191906000526020600020905b815481529060010190602001808311610eb057829003601f168201915b505050505081565b8015610ff657600073ffffffffffffffffffffffffffffffffffffffff16600a60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610f7357600080fd5b81600a60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555061110f565b600073ffffffffffffffffffffffffffffffffffffffff16600a60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141561108f57600080fd5b6000600a60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b8173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161116c9190611f50565b60405180910390a35050565b611184848484846115e6565b818373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4818373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167f75c9e114f073c346aac7d1d7e9a3c3c14edabcdd27de07d1d9e425f45d318c5e600b60008781526020019081526020016000206001600b6000898152602001908152602001600020805490506112659190612035565b8154811061129c577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600052602060002001546040516112b49190611f6b565b60405180910390a450505050565b60008173ffffffffffffffffffffffffffffffffffffffff16600a60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614905092915050565b60008060046000848152602001908152602001600020549050600381815481106113ad577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154915050919050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461141b57600080fd5b60606000606060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff169150600660008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054806020026020016040519081016040528092919081815260200182805480156114cd57602002820191906000526020600020905b8154815260200190600101908083116114b9575b5050505050905060005b815181101561153f5761152c838784848151811061151e577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020026020010151876115e6565b8080611537906121b6565b9150506114d7565b50846000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508473ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a360019350505050919050565b60006005600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508473ffffffffffffffffffffffffffffffffffffffff166005600085815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461168957600080fd5b3373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16146117bd573373ffffffffffffffffffffffffffffffffffffffff166009600085815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614806117b357503373ffffffffffffffffffffffffffffffffffffffff16600a60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b6117bc57600080fd5b5b60006009600085815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001600660008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054905061189e9190612035565b815481106118d5577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154600660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060076000868152602001908152602001600020548154811061196a577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200181905550600860008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008154809291906119c890612129565b9190505550600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020839080600181540180825580915050600190039060005260206000200160009091909190915055600860008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000815480929190611a83906121b6565b9190505550836005600085815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060005b8251811015611c0357828181518110611b1f577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916600b6000868152602001908152602001600020602083611bab91906121ff565b81548110611be2577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600052602060002001819055508080611bfb906121b6565b915050611add565b505050505050565b6000611c1e611c1984611fe8565b611fc3565b905082815260208101848484011115611c3657600080fd5b611c418482856120e7565b509392505050565b600081359050611c58816122fd565b92915050565b600081359050611c6d81612314565b92915050565b600081359050611c828161232b565b92915050565b600082601f830112611c9957600080fd5b8135611ca9848260208601611c0b565b91505092915050565b600081359050611cc181612342565b92915050565b600060208284031215611cd957600080fd5b6000611ce784828501611c49565b91505092915050565b60008060408385031215611d0357600080fd5b6000611d1185828601611c49565b9250506020611d2285828601611c49565b9150509250929050565b600080600060608486031215611d4157600080fd5b6000611d4f86828701611c49565b9350506020611d6086828701611c49565b9250506040611d7186828701611cb2565b9150509250925092565b60008060008060808587031215611d9157600080fd5b6000611d9f87828801611c49565b9450506020611db087828801611c49565b9350506040611dc187828801611cb2565b925050606085013567ffffffffffffffff811115611dde57600080fd5b611dea87828801611c88565b91505092959194509250565b60008060408385031215611e0957600080fd5b6000611e1785828601611c49565b9250506020611e2885828601611c5e565b9150509250929050565b60008060408385031215611e4557600080fd5b6000611e5385828601611c49565b9250506020611e6485828601611cb2565b9150509250929050565b600060208284031215611e8057600080fd5b6000611e8e84828501611c73565b91505092915050565b600060208284031215611ea957600080fd5b6000611eb784828501611cb2565b91505092915050565b611ec981612069565b82525050565b611ed88161207b565b82525050565b611ee781612087565b82525050565b6000611ef882612019565b611f028185612024565b9350611f128185602086016120f6565b611f1b816122ec565b840191505092915050565b611f2f816120dd565b82525050565b6000602082019050611f4a6000830184611ec0565b92915050565b6000602082019050611f656000830184611ecf565b92915050565b6000602082019050611f806000830184611ede565b92915050565b60006020820190508181036000830152611fa08184611eed565b905092915050565b6000602082019050611fbd6000830184611f26565b92915050565b6000611fcd611fde565b9050611fd98282612185565b919050565b6000604051905090565b600067ffffffffffffffff821115612003576120026122bd565b5b61200c826122ec565b9050602081019050919050565b600081519050919050565b600082825260208201905092915050565b6000612040826120dd565b915061204b836120dd565b92508282101561205e5761205d612230565b5b828203905092915050565b6000612074826120bd565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b838110156121145780820151818401526020810190506120f9565b83811115612123576000848401525b50505050565b6000612134826120dd565b9150600082141561214857612147612230565b5b600182039050919050565b6000600282049050600182168061216b57607f821691505b6020821081141561217f5761217e61228e565b5b50919050565b61218e826122ec565b810181811067ffffffffffffffff821117156121ad576121ac6122bd565b5b80604052505050565b60006121c1826120dd565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156121f4576121f3612230565b5b600182019050919050565b600061220a826120dd565b9150612215836120dd565b9250826122255761222461225f565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b61230681612069565b811461231157600080fd5b50565b61231d8161207b565b811461232857600080fd5b50565b61233481612091565b811461233f57600080fd5b50565b61234b816120dd565b811461235657600080fd5b5056fea26469706673582212203192308cf5bb460567ed09c15b7e3f3aac5a9f3acd7511e0b579ca56fffd9c1b64736f6c63430008030033 -\ No newline at end of file +60806040523480156200001157600080fd5b506040516200333f3803806200333f83398181016040528101906200003791906200022c565b82600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555081600c9080519060200190620000d0929190620000f3565b5080600d9080519060200190620000e9929190620000f3565b5050505062000472565b82805462000101906200037d565b90600052602060002090601f01602090048101928262000125576000855562000171565b82601f106200014057805160ff191683800117855562000171565b8280016001018555821562000171579182015b828111156200017057825182559160200191906001019062000153565b5b50905062000180919062000184565b5090565b5b808211156200019f57600081600090555060010162000185565b5090565b6000620001ba620001b484620002dd565b620002b4565b905082815260208101848484011115620001d357600080fd5b620001e084828562000347565b509392505050565b600081519050620001f98162000458565b92915050565b600082601f8301126200021157600080fd5b815162000223848260208601620001a3565b91505092915050565b6000806000606084860312156200024257600080fd5b60006200025286828701620001e8565b935050602084015167ffffffffffffffff8111156200027057600080fd5b6200027e86828701620001ff565b925050604084015167ffffffffffffffff8111156200029c57600080fd5b620002aa86828701620001ff565b9150509250925092565b6000620002c0620002d3565b9050620002ce8282620003b3565b919050565b6000604051905090565b600067ffffffffffffffff821115620002fb57620002fa62000418565b5b620003068262000447565b9050602081019050919050565b6000620003208262000327565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60005b83811015620003675780820151818401526020810190506200034a565b8381111562000377576000848401525b50505050565b600060028204905060018216806200039657607f821691505b60208210811415620003ad57620003ac620003e9565b5b50919050565b620003be8262000447565b810181811067ffffffffffffffff82111715620003e057620003df62000418565b5b80604052505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b620004638162000313565b81146200046f57600080fd5b50565b612ebd80620004826000396000f3fe608060405260043610610152576000357c01000000000000000000000000000000000000000000000000000000009004806370a08231116100c8578063b88d4fde1161008c578063b88d4fde14610456578063c87b56dd14610472578063dc7e7b14146104af578063e985e9c5146104ec578063f1b0aa1514610529578063f2fde38b1461056657610152565b806370a082311461036f5780638da5cb5b146103ac57806392088cf6146103d757806395d89b4114610402578063a22cb4651461042d57610152565b806323b872dd1161011a57806323b872dd146102435780632f745c591461025f57806342842e0e1461029c578063449a52f8146102b85780634f6ccce7146102f55780636352211e1461033257610152565b806301ffc9a71461015757806306fdde0314610194578063081812fc146101bf578063095ea7b3146101fc57806318160ddd14610218575b600080fd5b34801561016357600080fd5b5061017e600480360381019061017991906128eb565b6105a3565b60405161018b91906129cd565b60405180910390f35b3480156101a057600080fd5b506101a961074e565b6040516101b69190612a03565b60405180910390f35b3480156101cb57600080fd5b506101e660048036038101906101e19190612914565b6107dc565b6040516101f391906129b2565b60405180910390f35b61021660048036038101906102119190612886565b610819565b005b34801561022457600080fd5b5061022d610935565b60405161023a9190612a25565b60405180910390f35b61025d60048036038101906102589190612780565b610942565b005b34801561026b57600080fd5b5061028660048036038101906102819190612886565b6109b1565b6040516102939190612a25565b60405180910390f35b6102b660048036038101906102b19190612780565b610a88565b005b3480156102c457600080fd5b506102df60048036038101906102da9190612886565b610af7565b6040516102ec91906129cd565b60405180910390f35b34801561030157600080fd5b5061031c60048036038101906103179190612914565b610db9565b6040516103299190612a25565b60405180910390f35b34801561033e57600080fd5b5061035960048036038101906103549190612914565b610e07565b60405161036691906129b2565b60405180910390f35b34801561037b57600080fd5b506103966004803603810190610391919061271b565b610e44565b6040516103a39190612a25565b60405180910390f35b3480156103b857600080fd5b506103c1610e8d565b6040516103ce91906129b2565b60405180910390f35b3480156103e357600080fd5b506103ec610eb1565b6040516103f991906129b2565b60405180910390f35b34801561040e57600080fd5b50610417610ed7565b6040516104249190612a03565b60405180910390f35b34801561043957600080fd5b50610454600480360381019061044f919061284a565b610f65565b005b610470600480360381019061046b91906127cf565b611208565b005b34801561047e57600080fd5b5061049960048036038101906104949190612914565b611352565b6040516104a69190612a03565b60405180910390f35b3480156104bb57600080fd5b506104d660048036038101906104d191906128c2565b6113be565b6040516104e39190612a03565b60405180910390f35b3480156104f857600080fd5b50610513600480360381019061050e9190612744565b611d01565b60405161052091906129cd565b60405180910390f35b34801561053557600080fd5b50610550600480360381019061054b9190612914565b611d99565b60405161055d9190612a25565b60405180910390f35b34801561057257600080fd5b5061058d6004803603810190610588919061271b565b611dff565b60405161059a91906129cd565b60405180910390f35b60006380ac58cd7c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614156105f85760019050610749565b635b5e139f7c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561064b5760019050610749565b63780e9d637c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561069e5760019050610749565b63449a52f87c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614156106f15760019050610749565b6301ffc9a77c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614156107445760019050610749565b600090505b919050565b600c805461075b90612c6a565b80601f016020809104026020016040519081016040528092919081815260200182805461078790612c6a565b80156107d45780601f106107a9576101008083540402835291602001916107d4565b820191906000526020600020905b8154815290600101906020018083116107b757829003601f168201915b505050505081565b60006009600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b3373ffffffffffffffffffffffffffffffffffffffff166005600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461088457600080fd5b816009600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000600280549050905090565b606061095084848484612025565b818373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a450505050565b6000600860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205482106109fe57600080fd5b600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208281548110610a75577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154905092915050565b6060610a9684848484612025565b818373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a450505050565b60003373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610b5157600080fd5b600060046000848152602001908152602001600020541480610b7857506000600280549050145b610b8157600080fd5b600080600280549050915083905060028190806001815401808255809150506001900390600052602060002001600090919091909150556003439080600181540180825580915050600190039060005260206000200160009091909190915055846005600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508360076000600660008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002080549050815260200190815260200160002081905550600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020849080600181540180825580915050600190039060005260206000200160009091909190915055600860008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000815480929190610d4390612ccd565b91905055508473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fab8530f87dc9b59234c4623bf917212bb2536d647574c8e7e5da92c2ede0c9f886604051610da59190612a25565b60405180910390a360019250505092915050565b600060028281548110610df5577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600052602060002001549050919050565b60006005600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000600860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600d8054610ee490612c6a565b80601f0160208091040260200160405190810160405280929190818152602001828054610f1090612c6a565b8015610f5d5780601f10610f3257610100808354040283529160200191610f5d565b820191906000526020600020905b815481529060010190602001808311610f4057829003601f168201915b505050505081565b801561108657600073ffffffffffffffffffffffffffffffffffffffff16600a60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461100357600080fd5b81600a60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555061119f565b600073ffffffffffffffffffffffffffffffffffffffff16600a60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141561111f57600080fd5b6000600a60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b8173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516111fc91906129cd565b60405180910390a35050565b61121484848484612025565b818373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4818373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167f75c9e114f073c346aac7d1d7e9a3c3c14edabcdd27de07d1d9e425f45d318c5e600b60008781526020019081526020016000206001600b6000898152602001908152602001600020805490506112f59190612b3f565b8154811061132c577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b906000526020600020015460405161134491906129e8565b60405180910390a450505050565b60606113b760026004600085815260200190815260200160002054815481106113a4577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600052602060002001546001026113be565b9050919050565b606080600080604967ffffffffffffffff811115611405577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280601f01601f1916602001820160405280156114375781602001600182028036833780820191505090505b5092507f730000000000000000000000000000000000000000000000000000000000000083600081518110611495577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f68000000000000000000000000000000000000000000000000000000000000008360018151811061151f577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f6100000000000000000000000000000000000000000000000000000000000000836002815181106115a9577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f320000000000000000000000000000000000000000000000000000000000000083600381518110611633577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f3500000000000000000000000000000000000000000000000000000000000000836004815181106116bd577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f360000000000000000000000000000000000000000000000000000000000000083600581518110611747577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f3a00000000000000000000000000000000000000000000000000000000000000836006815181106117d1577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f2f000000000000000000000000000000000000000000000000000000000000008360078151811061185b577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f2f00000000000000000000000000000000000000000000000000000000000000836008815181106118e5577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506009905060005b6020811015611cf557600f86826020811061195f577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b1a7f0100000000000000000000000000000000000000000000000000000000000000027f01000000000000000000000000000000000000000000000000000000000000009004169250600a8360ff161015611a50576030836119c19190612b08565b7f010000000000000000000000000000000000000000000000000000000000000002848381518110611a1c577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350611ae8565b605783611a5d9190612b08565b7f010000000000000000000000000000000000000000000000000000000000000002848381518110611ab8577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053505b600460f0878360208110611b25577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b1a7f0100000000000000000000000000000000000000000000000000000000000000027f010000000000000000000000000000000000000000000000000000000000000090041660ff16908060020a82049150509250600a8360ff161015611c2f57603083611b949190612b08565b7f01000000000000000000000000000000000000000000000000000000000000000284600184611bc49190612ab2565b81518110611bfb577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350611cd3565b605783611c3c9190612b08565b7f01000000000000000000000000000000000000000000000000000000000000000284600184611c6c9190612ab2565b81518110611ca3577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053505b600282611ce09190612ab2565b91508080611ced90612ccd565b91505061191b565b50829350505050919050565b60008173ffffffffffffffffffffffffffffffffffffffff16600a60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614905092915050565b6000806004600084815260200190815260200160002054905060038181548110611dec577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154915050919050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611e5a57600080fd5b60606000606060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff169150600660008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805480602002602001604051908101604052809291908181526020018280548015611f0c57602002820191906000526020600020905b815481526020019060010190808311611ef8575b5050505050905060005b8151811015611f7e57611f6b8387848481518110611f5d577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001015187612025565b8080611f7690612ccd565b915050611f16565b50846000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508473ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a360019350505050919050565b60006005600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508473ffffffffffffffffffffffffffffffffffffffff166005600085815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146120c857600080fd5b3373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16146121fc573373ffffffffffffffffffffffffffffffffffffffff166009600085815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614806121f257503373ffffffffffffffffffffffffffffffffffffffff16600a60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b6121fb57600080fd5b5b60006009600085815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001600660008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805490506122dd9190612b3f565b81548110612314577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154600660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206007600086815260200190815260200160002054815481106123a9577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200181905550600860008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081548092919061240790612c40565b9190505550600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020839080600181540180825580915050600190039060005260206000200160009091909190915055600860008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008154809291906124c290612ccd565b9190505550836005600085815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060005b82518110156126425782818151811061255e577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916600b60008681526020019081526020016000206020836125ea9190612d16565b81548110612621577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200181905550808061263a90612ccd565b91505061251c565b505050505050565b600061265d61265884612a65565b612a40565b90508281526020810184848401111561267557600080fd5b612680848285612bfe565b509392505050565b60008135905061269781612e14565b92915050565b6000813590506126ac81612e2b565b92915050565b6000813590506126c181612e42565b92915050565b6000813590506126d681612e59565b92915050565b600082601f8301126126ed57600080fd5b81356126fd84826020860161264a565b91505092915050565b60008135905061271581612e70565b92915050565b60006020828403121561272d57600080fd5b600061273b84828501612688565b91505092915050565b6000806040838503121561275757600080fd5b600061276585828601612688565b925050602061277685828601612688565b9150509250929050565b60008060006060848603121561279557600080fd5b60006127a386828701612688565b93505060206127b486828701612688565b92505060406127c586828701612706565b9150509250925092565b600080600080608085870312156127e557600080fd5b60006127f387828801612688565b945050602061280487828801612688565b935050604061281587828801612706565b925050606085013567ffffffffffffffff81111561283257600080fd5b61283e878288016126dc565b91505092959194509250565b6000806040838503121561285d57600080fd5b600061286b85828601612688565b925050602061287c8582860161269d565b9150509250929050565b6000806040838503121561289957600080fd5b60006128a785828601612688565b92505060206128b885828601612706565b9150509250929050565b6000602082840312156128d457600080fd5b60006128e2848285016126b2565b91505092915050565b6000602082840312156128fd57600080fd5b600061290b848285016126c7565b91505092915050565b60006020828403121561292657600080fd5b600061293484828501612706565b91505092915050565b61294681612b73565b82525050565b61295581612b85565b82525050565b61296481612b91565b82525050565b600061297582612a96565b61297f8185612aa1565b935061298f818560208601612c0d565b61299881612e03565b840191505092915050565b6129ac81612be7565b82525050565b60006020820190506129c7600083018461293d565b92915050565b60006020820190506129e2600083018461294c565b92915050565b60006020820190506129fd600083018461295b565b92915050565b60006020820190508181036000830152612a1d818461296a565b905092915050565b6000602082019050612a3a60008301846129a3565b92915050565b6000612a4a612a5b565b9050612a568282612c9c565b919050565b6000604051905090565b600067ffffffffffffffff821115612a8057612a7f612dd4565b5b612a8982612e03565b9050602081019050919050565b600081519050919050565b600082825260208201905092915050565b6000612abd82612be7565b9150612ac883612be7565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115612afd57612afc612d47565b5b828201905092915050565b6000612b1382612bf1565b9150612b1e83612bf1565b92508260ff03821115612b3457612b33612d47565b5b828201905092915050565b6000612b4a82612be7565b9150612b5583612be7565b925082821015612b6857612b67612d47565b5b828203905092915050565b6000612b7e82612bc7565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b82818337600083830152505050565b60005b83811015612c2b578082015181840152602081019050612c10565b83811115612c3a576000848401525b50505050565b6000612c4b82612be7565b91506000821415612c5f57612c5e612d47565b5b600182039050919050565b60006002820490506001821680612c8257607f821691505b60208210811415612c9657612c95612da5565b5b50919050565b612ca582612e03565b810181811067ffffffffffffffff82111715612cc457612cc3612dd4565b5b80604052505050565b6000612cd882612be7565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415612d0b57612d0a612d47565b5b600182019050919050565b6000612d2182612be7565b9150612d2c83612be7565b925082612d3c57612d3b612d76565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b612e1d81612b73565b8114612e2857600080fd5b50565b612e3481612b85565b8114612e3f57600080fd5b50565b612e4b81612b91565b8114612e5657600080fd5b50565b612e6281612b9b565b8114612e6d57600080fd5b50565b612e7981612be7565b8114612e8457600080fd5b5056fea26469706673582212206901e2901da995d09801709d9f9bbe9acecf7287356ab4803b05f7cbfc9a7a0c64736f6c63430008030033 +\ No newline at end of file diff --git a/python/eth_badge/data/BadgeToken.json b/python/eth_badge/data/BadgeToken.json @@ -1 +1 @@ -[{"inputs":[{"internalType":"address","name":"_declarator","type":"address"},{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_owner","type":"address"},{"indexed":true,"internalType":"address","name":"_approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_owner","type":"address"},{"indexed":true,"internalType":"address","name":"_operator","type":"address"},{"indexed":false,"internalType":"bool","name":"_approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_minter","type":"address"},{"indexed":true,"internalType":"address","name":"_beneficiary","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":true,"internalType":"address","name":"_to","type":"address"},{"indexed":true,"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":true,"internalType":"address","name":"_to","type":"address"},{"indexed":true,"internalType":"uint256","name":"_tokenId","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"_data","type":"bytes32"}],"name":"TransferWithData","type":"event"},{"inputs":[{"internalType":"address","name":"_approved","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"declarator","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_beneficiary","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"mintTo","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"mintedAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_operator","type":"address"},{"internalType":"bool","name":"_approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceID","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_newOwner","type":"address"}],"name":"transferOwnership","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}] +[{"inputs":[{"internalType":"address","name":"_declarator","type":"address"},{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_owner","type":"address"},{"indexed":true,"internalType":"address","name":"_approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_owner","type":"address"},{"indexed":true,"internalType":"address","name":"_operator","type":"address"},{"indexed":false,"internalType":"bool","name":"_approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_minter","type":"address"},{"indexed":true,"internalType":"address","name":"_beneficiary","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":true,"internalType":"address","name":"_to","type":"address"},{"indexed":true,"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":true,"internalType":"address","name":"_to","type":"address"},{"indexed":true,"internalType":"uint256","name":"_tokenId","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"_data","type":"bytes32"}],"name":"TransferWithData","type":"event"},{"inputs":[{"internalType":"address","name":"_approved","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"declarator","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_beneficiary","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"mintTo","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"mintedAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_operator","type":"address"},{"internalType":"bool","name":"_approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceID","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_data","type":"bytes32"}],"name":"toAscii","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_newOwner","type":"address"}],"name":"transferOwnership","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}] diff --git a/python/eth_erc721/erc721.py b/python/eth_erc721/erc721.py @@ -129,6 +129,21 @@ class ERC721(ERC20, EIP173): return o + def token_uri(self, contract_address, token_id, sender_address=ZERO_ADDRESS): + o = jsonrpc_template() + o['method'] = 'eth_call' + enc = ABIContractEncoder() + enc.method('tokenURI') + enc.typ(ABIContractType.UINT256) + enc.uint256(token_id) + data = add_0x(enc.get()) + tx = self.template(sender_address, contract_address) + tx = self.set_code(tx, data) + o['params'].append(self.normalize(tx)) + o['params'].append('latest') + return o + + @classmethod def parse_owner_of(self, v): return abi_decode_single(ABIContractType.ADDRESS, v) @@ -162,3 +177,8 @@ class ERC721(ERC20, EIP173): @classmethod def parse_get_approved(self, v): return abi_decode_single(ABIContractType.ADDRESS, v) + + + @classmethod + def parse_token_uri(self, v): + return abi_decode_single(ABIContractType.STRING, v) diff --git a/python/tests/test_app.py b/python/tests/test_app.py @@ -245,5 +245,16 @@ class Test(EthTesterCase): self.assertEqual(self.accounts[4], owner_address) + def test_token_uri(self): + token_bytes = b'\xee' * 32 + token_id = int.from_bytes(token_bytes, byteorder='big') + c = self._mint(self.accounts[1], token_id) + + o = c.token_uri(self.address, token_id, sender_address=self.accounts[0]) + r = self.rpc.do(o) + uri = c.parse_token_uri(r) + self.assertEqual(uri, 'sha256://' + token_bytes.hex()) + + if __name__ == '__main__': unittest.main() diff --git a/solidity/BadgeToken.sol b/solidity/BadgeToken.sol @@ -156,6 +156,47 @@ contract BadgeToken { return tokenOwnerIndex[_owner][_index]; } + // TODO: move to library function? + function toAscii(bytes32 _data) public pure returns(string memory) { + bytes memory out; + uint8 t; + uint256 c; + + out = new bytes(64 + 9); + out[0] = "s"; + out[1] = "h"; + out[2] = "a"; + out[3] = "2"; + out[4] = "5"; + out[5] = "6"; + out[6] = ":"; + out[7] = "/"; + out[8] = "/"; + + c = 9; + for (uint256 i = 0; i < 32; i++) { + t = uint8(_data[i]) & 0x0f; + if (t < 10) { + out[c] = bytes1(t + 0x30); + } else { + out[c] = bytes1(t + 0x57); + } + t = (uint8(_data[i]) & 0xf0) >> 4; + if (t < 10) { + out[c+1] = bytes1(t + 0x30); + } else { + out[c+1] = bytes1(t + 0x57); + } + c += 2; + } + return string(out); + } + + // ERC-721 (Metadata - optional) + function tokenURI(uint256 _tokenId) public view returns (string memory) { + return toAscii(bytes32(token[tokenIndex[_tokenId]])); + } + // Minter function mintTo(address _beneficiary, uint256 _tokenId) external returns (bool) { require(owner == msg.sender);