craft-nft

A standalone NFT implementation for real-world arts and crafts assets
Log | Files | Refs | README

commit b4bf1132d829001419a30bccaaf85e1b465a5554
parent 6347b668a2a6890fff9d1444d44cc11b8f8094af
Author: lash <dev@holbrook.no>
Date:   Fri, 16 Dec 2022 21:48:23 +0000

Add digest and uri generate

Diffstat:
Mpython/eth_craft_nft/data/CraftNFT.bin | 4++--
Mpython/eth_craft_nft/data/CraftNFT.json | 2+-
Mpython/eth_craft_nft/nft.py | 17+++++++++++++++++
Mpython/tests/test_basic.py | 88+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msolidity/CraftNFT.sol | 25+++++++++++++++++--------
5 files changed, 125 insertions(+), 11 deletions(-)

diff --git a/python/eth_craft_nft/data/CraftNFT.bin b/python/eth_craft_nft/data/CraftNFT.bin @@ -1 +1 @@ -60806040523480156200001157600080fd5b506040516200307038038062003070833981810160405281019062000037919062000236565b336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555081600690816200008891906200050c565b5080600790816200009a91906200050c565b505050620005f3565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6200010c82620000c1565b810181811067ffffffffffffffff821117156200012e576200012d620000d2565b5b80604052505050565b600062000143620000a3565b905062000151828262000101565b919050565b600067ffffffffffffffff821115620001745762000173620000d2565b5b6200017f82620000c1565b9050602081019050919050565b60005b83811015620001ac5780820151818401526020810190506200018f565b60008484015250505050565b6000620001cf620001c98462000156565b62000137565b905082815260208101848484011115620001ee57620001ed620000bc565b5b620001fb8482856200018c565b509392505050565b600082601f8301126200021b576200021a620000b7565b5b81516200022d848260208601620001b8565b91505092915050565b6000806040838503121562000250576200024f620000ad565b5b600083015167ffffffffffffffff811115620002715762000270620000b2565b5b6200027f8582860162000203565b925050602083015167ffffffffffffffff811115620002a357620002a2620000b2565b5b620002b18582860162000203565b9150509250929050565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200030e57607f821691505b602082108103620003245762000323620002c6565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b60008160020a8302905092915050565b600060088302620003917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826200034f565b6200039d86836200034f565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b6000620003ea620003e4620003de84620003b5565b620003bf565b620003b5565b9050919050565b6000819050919050565b6200040683620003c9565b6200041e6200041582620003f1565b8484546200035f565b825550505050565b600090565b6200043562000426565b62000442818484620003fb565b505050565b5b818110156200046a576200045e6000826200042b565b60018101905062000448565b5050565b601f821115620004b95762000483816200032a565b6200048e846200033f565b810160208510156200049e578190505b620004b6620004ad856200033f565b83018262000447565b50505b505050565b60008160020a8304905092915050565b6000620004e160001984600802620004be565b1980831691505092915050565b6000620004fc8383620004ce565b9150826002028217905092915050565b6200051782620002bb565b67ffffffffffffffff811115620005335762000532620000d2565b5b6200053f8254620002f5565b6200054c8282856200046e565b600060209050601f8311600181146200058457600084156200056f578287015190505b6200057b8582620004ee565b865550620005eb565b601f19841662000594866200032a565b60005b82811015620005be5784890151825560018201915060208501945060208101905062000597565b86831015620005de5784890151620005da601f891682620004ce565b8355505b6001600288020188555050505b505050505050565b612a6d80620006036000396000f3fe60806040526004361061015d576000357c01000000000000000000000000000000000000000000000000000000009004806370a08231116100d3578063b9adc41b1161008c578063b9adc41b146104c4578063bee2c0b514610501578063c87b56dd1461053e578063c9796c391461057b578063e985e9c5146105b8578063f9613ab2146105f55761015d565b806370a08231146103af5780638da5cb5b146103ec57806395d89b4114610417578063a22cb46514610442578063adf288df1461046b578063b88d4fde146104a85761015d565b806325cbaa181161012557806325cbaa181461026057806342842e0e1461029d5780634d03546a146102b95780634f64b2be146102f6578063559f5dc9146103335780636352211e146103725761015d565b806301ffc9a71461016257806306fdde031461019f578063081812fc146101ca57806323b872dd1461020757806324e0febc14610223575b600080fd5b34801561016e57600080fd5b5061018960048036038101906101849190612010565b610632565b6040516101969190612058565b60405180910390f35b3480156101ab57600080fd5b506101b46107d8565b6040516101c19190612103565b60405180910390f35b3480156101d657600080fd5b506101f160048036038101906101ec919061215b565b610866565b6040516101fe91906121c9565b60405180910390f35b610221600480360381019061021c9190612210565b6108a3565b005b34801561022f57600080fd5b5061024a60048036038101906102459190612299565b610912565b60405161025791906122d5565b60405180910390f35b34801561026c57600080fd5b50610287600480360381019061028291906122f0565b61092a565b60405161029491906122d5565b60405180910390f35b6102b760048036038101906102b29190612210565b610b5a565b005b3480156102c557600080fd5b506102e060048036038101906102db9190612381565b610bc9565b6040516102ed9190612058565b60405180910390f35b34801561030257600080fd5b5061031d6004803603810190610318919061215b565b610e07565b60405161032a91906122d5565b60405180910390f35b34801561033f57600080fd5b5061035a600480360381019061035591906123c1565b610e2b565b60405161036993929190612410565b60405180910390f35b34801561037e57600080fd5b506103996004803603810190610394919061215b565b610ea4565b6040516103a691906121c9565b60405180910390f35b3480156103bb57600080fd5b506103d660048036038101906103d19190612447565b610ee0565b6040516103e39190612483565b60405180910390f35b3480156103f857600080fd5b50610401610ee7565b60405161040e91906121c9565b60405180910390f35b34801561042357600080fd5b5061042c610f0b565b6040516104399190612103565b60405180910390f35b34801561044e57600080fd5b50610469600480360381019061046491906124ca565b610f99565b005b34801561047757600080fd5b50610492600480360381019061048d919061250a565b61123b565b60405161049f91906122d5565b60405180910390f35b6104c260048036038101906104bd919061267f565b6112c4565b005b3480156104d057600080fd5b506104eb60048036038101906104e69190612299565b61139b565b6040516104f89190612058565b60405180910390f35b34801561050d57600080fd5b5061052860048036038101906105239190612702565b6113cd565b604051610535919061276e565b60405180910390f35b34801561054a57600080fd5b506105656004803603810190610560919061215b565b6114a0565b6040516105729190612103565b60405180910390f35b34801561058757600080fd5b506105a2600480360381019061059d9190612299565b611550565b6040516105af9190612103565b60405180910390f35b3480156105c457600080fd5b506105df60048036038101906105da9190612789565b611b6b565b6040516105ec9190612058565b60405180910390f35b34801561060157600080fd5b5061061c60048036038101906106179190612299565b611c03565b60405161062991906122d5565b60405180910390f35b60006380ac58cd7c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19160361068657600190506107d3565b635b5e139f7c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916036106d857600190506107d3565b63780e9d637c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19160361072a57600190506107d3565b63449a52f87c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19160361077c57600190506107d3565b6301ffc9a77c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916036107ce57600190506107d3565b600090505b919050565b600680546107e5906127f8565b80601f0160208091040260200160405190810160405280929190818152602001828054610811906127f8565b801561085e5780601f106108335761010080835404028352916020019161085e565b820191906000526020600020905b81548152906001019060200180831161084157829003601f168201915b505050505081565b60006004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b60606108b184848484611c70565b818373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a450505050565b60036020528060005260406000206000915090505481565b60008060008060026000878152602001908152602001600020858154811061095557610954612829565b5b90600052602060002001905060008514801561098f575060008160000160009054906101000a900465ffffffffffff1665ffffffffffff16145b156109f057600181600001600c8282829054906101000a900465ffffffffffff166109ba9190612887565b92506101000a81548165ffffffffffff021916908365ffffffffffff1602179055506109e6878761123b565b9350505050610b53565b8060000160009054906101000a900465ffffffffffff1665ffffffffffff1681600001600c9054906101000a900465ffffffffffff1665ffffffffffff1610610a3857600080fd5b65ffffffffffff866001900416915060c8829060020a0291507f8000000000000000000000000000000000000000000000000000000000000000821791508673ffffffffffffffffffffffffffffffffffffffff16821791507fffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000086600190041692506028859060020a028317925080600001600c9054906101000a900465ffffffffffff1665ffffffffffff1683179250600181600001600c8282829054906101000a900465ffffffffffff16610b0f9190612887565b92506101000a81548165ffffffffffff021916908365ffffffffffff1602179055508160010260036000856001028152602001908152602001600020819055505050505b9392505050565b6060610b6884848484611c70565b818373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a450505050565b60008060008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610c2757600080fd5b610c2f611f6b565b600260008781526020019081526020016000208054905092506000831115610cff57600060026000888152602001908152602001600020600081548110610c7957610c78612829565b5b9060005260206000200160000160009054906101000a900465ffffffffffff1665ffffffffffff1611610cab57600080fd5b60026000878152602001908152602001600020600184610ccb91906128c1565b81548110610cdc57610cdb612829565b5b9060005260206000200160000160069054906101000a900465ffffffffffff1691505b84816000019065ffffffffffff16908165ffffffffffff16815250508482610d279190612887565b816020019065ffffffffffff16908165ffffffffffff168152505060026000878152602001908152602001600020819080600181540180825580915050600190039060005260206000200160009091909190915060008201518160000160006101000a81548165ffffffffffff021916908365ffffffffffff16021790555060208201518160000160066101000a81548165ffffffffffff021916908365ffffffffffff160217905550604082015181600001600c6101000a81548165ffffffffffff021916908365ffffffffffff160217905550505050505092915050565b60018181548110610e1757600080fd5b906000526020600020016000915090505481565b60026020528160005260406000208181548110610e4757600080fd5b90600052602060002001600091509150508060000160009054906101000a900465ffffffffffff16908060000160069054906101000a900465ffffffffffff169080600001600c9054906101000a900465ffffffffffff16905083565b600080600360008460010281526020019081526020016000205490506060819060020a026c010000000000000000000000009004915050919050565b6000919050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60078054610f18906127f8565b80601f0160208091040260200160405190810160405280929190818152602001828054610f44906127f8565b8015610f915780601f10610f6657610100808354040283529160200191610f91565b820191906000526020600020905b815481529060010190602001808311610f7457829003601f168201915b505050505081565b80156110ba57600073ffffffffffffffffffffffffffffffffffffffff16600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461103757600080fd5b81600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506111d2565b600073ffffffffffffffffffffffffffffffffffffffff16600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff160361115257600080fd5b6000600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b8173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161122f9190612058565b60405180910390a35050565b600080600060010260036000858152602001908152602001600020541461126157600080fd5b8373ffffffffffffffffffffffffffffffffffffffff1690507f8000000000000000000000000000000000000000000000000000000000000000811790508060010260036000858152602001908152602001600020819055508291505092915050565b6112d084848484611c70565b818373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4818373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167f75c9e114f073c346aac7d1d7e9a3c3c14edabcdd27de07d1d9e425f45d318c5e600060010260405161138d91906122d5565b60405180910390a450505050565b6000807f8000000000000000000000000000000000000000000000000000000000000000836001900416119050919050565b6000808290505b600260008681526020019081526020016000208054905081101561147457836fffffffffffffffffffffffffffffffff1660026000878152602001908152602001600020828154811061142a57611429612829565b5b9060005260206000200160000160069054906101000a900465ffffffffffff1665ffffffffffff1611156114615780915050611499565b808061146c906128f5565b9150506113d4565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90505b9392505050565b606060003073ffffffffffffffffffffffffffffffffffffffff1663f9613ab2846001026040518263ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004016114fc91906122d5565b602060405180830381865afa158015611519573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061153d9190612952565b905061154881611550565b915050919050565b606080600080604767ffffffffffffffff81111561157157611570612554565b5b6040519080825280601f01601f1916602001820160405280156115a35781602001600182028036833780820191505090505b5092507f7300000000000000000000000000000000000000000000000000000000000000836000815181106115db576115da612829565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f68000000000000000000000000000000000000000000000000000000000000008360018151811061163f5761163e612829565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f6100000000000000000000000000000000000000000000000000000000000000836002815181106116a3576116a2612829565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f32000000000000000000000000000000000000000000000000000000000000008360038151811061170757611706612829565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f35000000000000000000000000000000000000000000000000000000000000008360048151811061176b5761176a612829565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f3600000000000000000000000000000000000000000000000000000000000000836005815181106117cf576117ce612829565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f3a000000000000000000000000000000000000000000000000000000000000008360068151811061183357611832612829565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506007905060005b6020811015611b5f57600460f087836020811061188957611888612829565b5b1a7f0100000000000000000000000000000000000000000000000000000000000000027f010000000000000000000000000000000000000000000000000000000000000090041660ff16908060020a82049150509250600a8360ff161015611961576030836118f8919061298c565b7f01000000000000000000000000000000000000000000000000000000000000000284838151811061192d5761192c612829565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506119d3565b60578361196e919061298c565b7f0100000000000000000000000000000000000000000000000000000000000000028483815181106119a3576119a2612829565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053505b600f8682602081106119e8576119e7612829565b5b1a7f0100000000000000000000000000000000000000000000000000000000000000027f01000000000000000000000000000000000000000000000000000000000000009004169250600a8360ff161015611abf57603083611a4a919061298c565b7f01000000000000000000000000000000000000000000000000000000000000000284600184611a7a91906129c1565b81518110611a8b57611a8a612829565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350611b3d565b605783611acc919061298c565b7f01000000000000000000000000000000000000000000000000000000000000000284600184611afc91906129c1565b81518110611b0d57611b0c612829565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053505b600282611b4a91906129c1565b91508080611b57906128f5565b915050611869565b50829350505050919050565b60008173ffffffffffffffffffffffffffffffffffffffff16600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614905092915050565b60008060036000848152602001908152602001600020549050611c258161139b565b611c2e57600080fd5b60a081908060020a820491505090507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000060010283168117905080915050919050565b60003073ffffffffffffffffffffffffffffffffffffffff16636352211e846040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401611cc79190612483565b602060405180830381865afa158015611ce4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d089190612a0a565b90508473ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611d4257600080fd5b3373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614611e76573373ffffffffffffffffffffffffffffffffffffffff166004600085815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161480611e6c57503373ffffffffffffffffffffffffffffffffffffffff16600560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b611e7557600080fd5b5b60006004600085815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550611ed38385611eda565b5050505050565b600080836001029050600360008281526020019081526020016000205460019004915060008203611f0a57600080fd5b7fffffffffffffffffffffffff0000000000000000000000000000000000000000821691508273ffffffffffffffffffffffffffffffffffffffff168217915081600102600360008381526020019081526020016000208190555050505050565b6040518060600160405280600065ffffffffffff168152602001600065ffffffffffff168152602001600065ffffffffffff1681525090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b611fed81611fb8565b8114611ff857600080fd5b50565b60008135905061200a81611fe4565b92915050565b60006020828403121561202657612025611fae565b5b600061203484828501611ffb565b91505092915050565b60008115159050919050565b6120528161203d565b82525050565b600060208201905061206d6000830184612049565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156120ad578082015181840152602081019050612092565b60008484015250505050565b6000601f19601f8301169050919050565b60006120d582612073565b6120df818561207e565b93506120ef81856020860161208f565b6120f8816120b9565b840191505092915050565b6000602082019050818103600083015261211d81846120ca565b905092915050565b6000819050919050565b61213881612125565b811461214357600080fd5b50565b6000813590506121558161212f565b92915050565b60006020828403121561217157612170611fae565b5b600061217f84828501612146565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006121b382612188565b9050919050565b6121c3816121a8565b82525050565b60006020820190506121de60008301846121ba565b92915050565b6121ed816121a8565b81146121f857600080fd5b50565b60008135905061220a816121e4565b92915050565b60008060006060848603121561222957612228611fae565b5b6000612237868287016121fb565b9350506020612248868287016121fb565b925050604061225986828701612146565b9150509250925092565b6000819050919050565b61227681612263565b811461228157600080fd5b50565b6000813590506122938161226d565b92915050565b6000602082840312156122af576122ae611fae565b5b60006122bd84828501612284565b91505092915050565b6122cf81612263565b82525050565b60006020820190506122ea60008301846122c6565b92915050565b60008060006060848603121561230957612308611fae565b5b6000612317868287016121fb565b935050602061232886828701612284565b925050604061233986828701612146565b9150509250925092565b600065ffffffffffff82169050919050565b61235e81612343565b811461236957600080fd5b50565b60008135905061237b81612355565b92915050565b6000806040838503121561239857612397611fae565b5b60006123a685828601612284565b92505060206123b78582860161236c565b9150509250929050565b600080604083850312156123d8576123d7611fae565b5b60006123e685828601612284565b92505060206123f785828601612146565b9150509250929050565b61240a81612343565b82525050565b60006060820190506124256000830186612401565b6124326020830185612401565b61243f6040830184612401565b949350505050565b60006020828403121561245d5761245c611fae565b5b600061246b848285016121fb565b91505092915050565b61247d81612125565b82525050565b60006020820190506124986000830184612474565b92915050565b6124a78161203d565b81146124b257600080fd5b50565b6000813590506124c48161249e565b92915050565b600080604083850312156124e1576124e0611fae565b5b60006124ef858286016121fb565b9250506020612500858286016124b5565b9150509250929050565b6000806040838503121561252157612520611fae565b5b600061252f858286016121fb565b925050602061254085828601612284565b9150509250929050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61258c826120b9565b810181811067ffffffffffffffff821117156125ab576125aa612554565b5b80604052505050565b60006125be611fa4565b90506125ca8282612583565b919050565b600067ffffffffffffffff8211156125ea576125e9612554565b5b6125f3826120b9565b9050602081019050919050565b82818337600083830152505050565b600061262261261d846125cf565b6125b4565b90508281526020810184848401111561263e5761263d61254f565b5b612649848285612600565b509392505050565b600082601f8301126126665761266561254a565b5b813561267684826020860161260f565b91505092915050565b6000806000806080858703121561269957612698611fae565b5b60006126a7878288016121fb565b94505060206126b8878288016121fb565b93505060406126c987828801612146565b925050606085013567ffffffffffffffff8111156126ea576126e9611fb3565b5b6126f687828801612651565b91505092959194509250565b60008060006060848603121561271b5761271a611fae565b5b600061272986828701612284565b935050602061273a86828701612146565b925050604061274b86828701612146565b9150509250925092565b6000819050919050565b61276881612755565b82525050565b6000602082019050612783600083018461275f565b92915050565b600080604083850312156127a05761279f611fae565b5b60006127ae858286016121fb565b92505060206127bf858286016121fb565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061281057607f821691505b602082108103612823576128226127c9565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061289282612343565b915061289d83612343565b9250828201905065ffffffffffff8111156128bb576128ba612858565b5b92915050565b60006128cc82612125565b91506128d783612125565b92508282039050818111156128ef576128ee612858565b5b92915050565b600061290082612125565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361293257612931612858565b5b600182019050919050565b60008151905061294c8161226d565b92915050565b60006020828403121561296857612967611fae565b5b60006129768482850161293d565b91505092915050565b600060ff82169050919050565b60006129978261297f565b91506129a28361297f565b9250828201905060ff8111156129bb576129ba612858565b5b92915050565b60006129cc82612125565b91506129d783612125565b92508282019050808211156129ef576129ee612858565b5b92915050565b600081519050612a04816121e4565b92915050565b600060208284031215612a2057612a1f611fae565b5b6000612a2e848285016129f5565b9150509291505056fea2646970667358221220d1f144a35f3a21cac18c88d05e3e6a80b152eaf539c1b14862eebc5ffc16256964736f6c63430008110033 -\ No newline at end of file +60806040523480156200001157600080fd5b506040516200309838038062003098833981810160405281019062000037919062000236565b336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555081600690816200008891906200050c565b5080600790816200009a91906200050c565b505050620005f3565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6200010c82620000c1565b810181811067ffffffffffffffff821117156200012e576200012d620000d2565b5b80604052505050565b600062000143620000a3565b905062000151828262000101565b919050565b600067ffffffffffffffff821115620001745762000173620000d2565b5b6200017f82620000c1565b9050602081019050919050565b60005b83811015620001ac5780820151818401526020810190506200018f565b60008484015250505050565b6000620001cf620001c98462000156565b62000137565b905082815260208101848484011115620001ee57620001ed620000bc565b5b620001fb8482856200018c565b509392505050565b600082601f8301126200021b576200021a620000b7565b5b81516200022d848260208601620001b8565b91505092915050565b6000806040838503121562000250576200024f620000ad565b5b600083015167ffffffffffffffff811115620002715762000270620000b2565b5b6200027f8582860162000203565b925050602083015167ffffffffffffffff811115620002a357620002a2620000b2565b5b620002b18582860162000203565b9150509250929050565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200030e57607f821691505b602082108103620003245762000323620002c6565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b60008160020a8302905092915050565b600060088302620003917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826200034f565b6200039d86836200034f565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b6000620003ea620003e4620003de84620003b5565b620003bf565b620003b5565b9050919050565b6000819050919050565b6200040683620003c9565b6200041e6200041582620003f1565b8484546200035f565b825550505050565b600090565b6200043562000426565b62000442818484620003fb565b505050565b5b818110156200046a576200045e6000826200042b565b60018101905062000448565b5050565b601f821115620004b95762000483816200032a565b6200048e846200033f565b810160208510156200049e578190505b620004b6620004ad856200033f565b83018262000447565b50505b505050565b60008160020a8304905092915050565b6000620004e160001984600802620004be565b1980831691505092915050565b6000620004fc8383620004ce565b9150826002028217905092915050565b6200051782620002bb565b67ffffffffffffffff811115620005335762000532620000d2565b5b6200053f8254620002f5565b6200054c8282856200046e565b600060209050601f8311600181146200058457600084156200056f578287015190505b6200057b8582620004ee565b865550620005eb565b601f19841662000594866200032a565b60005b82811015620005be5784890151825560018201915060208501945060208101905062000597565b86831015620005de5784890151620005da601f891682620004ce565b8355505b6001600288020188555050505b505050505050565b612a9580620006036000396000f3fe608060405260043610610152576000357c01000000000000000000000000000000000000000000000000000000009004806370a08231116100c8578063b88d4fde1161008c578063b88d4fde1461049d578063bee2c0b5146104b9578063c87b56dd146104f6578063c9796c3914610533578063e985e9c514610570578063f9613ab2146105ad57610152565b806370a08231146103a45780638da5cb5b146103e157806395d89b411461040c578063a22cb46514610437578063adf288df1461046057610152565b806325cbaa181161011a57806325cbaa181461025557806342842e0e146102925780634d03546a146102ae5780634f64b2be146102eb578063559f5dc9146103285780636352211e1461036757610152565b806301ffc9a71461015757806306fdde0314610194578063081812fc146101bf57806323b872dd146101fc57806324e0febc14610218575b600080fd5b34801561016357600080fd5b5061017e60048036038101906101799190612038565b6105ea565b60405161018b9190612080565b60405180910390f35b3480156101a057600080fd5b506101a9610790565b6040516101b6919061212b565b60405180910390f35b3480156101cb57600080fd5b506101e660048036038101906101e19190612183565b61081e565b6040516101f391906121f1565b60405180910390f35b61021660048036038101906102119190612238565b61085b565b005b34801561022457600080fd5b5061023f600480360381019061023a91906122c1565b6108ca565b60405161024c91906122fd565b60405180910390f35b34801561026157600080fd5b5061027c60048036038101906102779190612318565b6108e2565b60405161028991906122fd565b60405180910390f35b6102ac60048036038101906102a79190612238565b610b11565b005b3480156102ba57600080fd5b506102d560048036038101906102d091906123a9565b610b80565b6040516102e29190612080565b60405180910390f35b3480156102f757600080fd5b50610312600480360381019061030d9190612183565b610dbe565b60405161031f91906122fd565b60405180910390f35b34801561033457600080fd5b5061034f600480360381019061034a91906123e9565b610de2565b60405161035e93929190612438565b60405180910390f35b34801561037357600080fd5b5061038e60048036038101906103899190612183565b610e5b565b60405161039b91906121f1565b60405180910390f35b3480156103b057600080fd5b506103cb60048036038101906103c6919061246f565b610e97565b6040516103d891906124ab565b60405180910390f35b3480156103ed57600080fd5b506103f6610e9e565b60405161040391906121f1565b60405180910390f35b34801561041857600080fd5b50610421610ec2565b60405161042e919061212b565b60405180910390f35b34801561044357600080fd5b5061045e600480360381019061045991906124f2565b610f50565b005b34801561046c57600080fd5b5061048760048036038101906104829190612532565b6111f2565b60405161049491906122fd565b60405180910390f35b6104b760048036038101906104b291906126a7565b61127b565b005b3480156104c557600080fd5b506104e060048036038101906104db919061272a565b611352565b6040516104ed9190612796565b60405180910390f35b34801561050257600080fd5b5061051d60048036038101906105189190612183565b611425565b60405161052a919061212b565b60405180910390f35b34801561053f57600080fd5b5061055a600480360381019061055591906122c1565b6114d5565b604051610567919061212b565b60405180910390f35b34801561057c57600080fd5b50610597600480360381019061059291906127b1565b611af0565b6040516105a49190612080565b60405180910390f35b3480156105b957600080fd5b506105d460048036038101906105cf91906122c1565b611b88565b6040516105e191906122fd565b60405180910390f35b60006380ac58cd7c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19160361063e576001905061078b565b635b5e139f7c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603610690576001905061078b565b63780e9d637c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916036106e2576001905061078b565b63449a52f87c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603610734576001905061078b565b6301ffc9a77c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603610786576001905061078b565b600090505b919050565b6006805461079d90612820565b80601f01602080910402602001604051908101604052809291908181526020018280546107c990612820565b80156108165780601f106107eb57610100808354040283529160200191610816565b820191906000526020600020905b8154815290600101906020018083116107f957829003601f168201915b505050505081565b60006004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b606061086984848484611c34565b818373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a450505050565b60036020528060005260406000206000915090505481565b60008060008060026000878152602001908152602001600020858154811061090d5761090c612851565b5b906000526020600020019050600085148015610947575060008160000160009054906101000a900465ffffffffffff1665ffffffffffff16145b156109a857600181600001600c8282829054906101000a900465ffffffffffff1661097291906128af565b92506101000a81548165ffffffffffff021916908365ffffffffffff16021790555061099e87876111f2565b9350505050610b0a565b8060000160009054906101000a900465ffffffffffff1665ffffffffffff1681600001600c9054906101000a900465ffffffffffff1665ffffffffffff16106109f057600080fd5b64ffffffffff866001900416915060d0829060020a0291507f8000000000000000000000000000000000000000000000000000000000000000821791508673ffffffffffffffffffffffffffffffffffffffff16821791507fffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000086600190041692506014859060020a028317925080600001600c9054906101000a900465ffffffffffff1665ffffffffffff1683179250600181600001600c8282829054906101000a900465ffffffffffff16610ac691906128af565b92506101000a81548165ffffffffffff021916908365ffffffffffff1602179055508160010260036000856001028152602001908152602001600020819055505050505b9392505050565b6060610b1f84848484611c34565b818373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a450505050565b60008060008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610bde57600080fd5b610be6611f93565b600260008781526020019081526020016000208054905092506000831115610cb657600060026000888152602001908152602001600020600081548110610c3057610c2f612851565b5b9060005260206000200160000160009054906101000a900465ffffffffffff1665ffffffffffff1611610c6257600080fd5b60026000878152602001908152602001600020600184610c8291906128e9565b81548110610c9357610c92612851565b5b9060005260206000200160000160069054906101000a900465ffffffffffff1691505b84816000019065ffffffffffff16908165ffffffffffff16815250508482610cde91906128af565b816020019065ffffffffffff16908165ffffffffffff168152505060026000878152602001908152602001600020819080600181540180825580915050600190039060005260206000200160009091909190915060008201518160000160006101000a81548165ffffffffffff021916908365ffffffffffff16021790555060208201518160000160066101000a81548165ffffffffffff021916908365ffffffffffff160217905550604082015181600001600c6101000a81548165ffffffffffff021916908365ffffffffffff160217905550505050505092915050565b60018181548110610dce57600080fd5b906000526020600020016000915090505481565b60026020528160005260406000208181548110610dfe57600080fd5b90600052602060002001600091509150508060000160009054906101000a900465ffffffffffff16908060000160069054906101000a900465ffffffffffff169080600001600c9054906101000a900465ffffffffffff16905083565b600080600360008460010281526020019081526020016000205490506060819060020a026c010000000000000000000000009004915050919050565b6000919050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60078054610ecf90612820565b80601f0160208091040260200160405190810160405280929190818152602001828054610efb90612820565b8015610f485780601f10610f1d57610100808354040283529160200191610f48565b820191906000526020600020905b815481529060010190602001808311610f2b57829003601f168201915b505050505081565b801561107157600073ffffffffffffffffffffffffffffffffffffffff16600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610fee57600080fd5b81600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550611189565b600073ffffffffffffffffffffffffffffffffffffffff16600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff160361110957600080fd5b6000600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b8173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516111e69190612080565b60405180910390a35050565b600080600060010260036000858152602001908152602001600020541461121857600080fd5b8373ffffffffffffffffffffffffffffffffffffffff1690507fc000000000000000000000000000000000000000000000000000000000000000811790508060010260036000858152602001908152602001600020819055508291505092915050565b61128784848484611c34565b818373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4818373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167f75c9e114f073c346aac7d1d7e9a3c3c14edabcdd27de07d1d9e425f45d318c5e600060010260405161134491906122fd565b60405180910390a450505050565b6000808290505b60026000868152602001908152602001600020805490508110156113f957836fffffffffffffffffffffffffffffffff166002600087815260200190815260200160002082815481106113af576113ae612851565b5b9060005260206000200160000160069054906101000a900465ffffffffffff1665ffffffffffff1611156113e6578091505061141e565b80806113f19061291d565b915050611359565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90505b9392505050565b606060003073ffffffffffffffffffffffffffffffffffffffff1663f9613ab2846001026040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040161148191906122fd565b602060405180830381865afa15801561149e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114c2919061297a565b90506114cd816114d5565b915050919050565b606080600080604767ffffffffffffffff8111156114f6576114f561257c565b5b6040519080825280601f01601f1916602001820160405280156115285781602001600182028036833780820191505090505b5092507f7300000000000000000000000000000000000000000000000000000000000000836000815181106115605761155f612851565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f6800000000000000000000000000000000000000000000000000000000000000836001815181106115c4576115c3612851565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f61000000000000000000000000000000000000000000000000000000000000008360028151811061162857611627612851565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f32000000000000000000000000000000000000000000000000000000000000008360038151811061168c5761168b612851565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f3500000000000000000000000000000000000000000000000000000000000000836004815181106116f0576116ef612851565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f36000000000000000000000000000000000000000000000000000000000000008360058151811061175457611753612851565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f3a00000000000000000000000000000000000000000000000000000000000000836006815181106117b8576117b7612851565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506007905060005b6020811015611ae457600460f087836020811061180e5761180d612851565b5b1a7f0100000000000000000000000000000000000000000000000000000000000000027f010000000000000000000000000000000000000000000000000000000000000090041660ff16908060020a82049150509250600a8360ff1610156118e65760308361187d91906129b4565b7f0100000000000000000000000000000000000000000000000000000000000000028483815181106118b2576118b1612851565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350611958565b6057836118f391906129b4565b7f01000000000000000000000000000000000000000000000000000000000000000284838151811061192857611927612851565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053505b600f86826020811061196d5761196c612851565b5b1a7f0100000000000000000000000000000000000000000000000000000000000000027f01000000000000000000000000000000000000000000000000000000000000009004169250600a8360ff161015611a44576030836119cf91906129b4565b7f010000000000000000000000000000000000000000000000000000000000000002846001846119ff91906129e9565b81518110611a1057611a0f612851565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350611ac2565b605783611a5191906129b4565b7f01000000000000000000000000000000000000000000000000000000000000000284600184611a8191906129e9565b81518110611a9257611a91612851565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053505b600282611acf91906129e9565b91508080611adc9061291d565b9150506117ee565b50829350505050919050565b60008173ffffffffffffffffffffffffffffffffffffffff16600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614905092915050565b60008060036000848152602001908152602001600020549050611baa81611e9e565b611bb357600080fd5b611bbc81611ed0565b15611bca5782915050611c2f565b7effffffffff00000000000000000000000000000000000000000000000000006001028116905060d081908060020a820491505090507fffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000600102831681179050809150505b919050565b60003073ffffffffffffffffffffffffffffffffffffffff16636352211e846040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401611c8b91906124ab565b602060405180830381865afa158015611ca8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ccc9190612a32565b90508473ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611d0657600080fd5b3373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614611e3a573373ffffffffffffffffffffffffffffffffffffffff166004600085815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161480611e3057503373ffffffffffffffffffffffffffffffffffffffff16600560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b611e3957600080fd5b5b60006004600085815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550611e978385611f02565b5050505050565b6000807f8000000000000000000000000000000000000000000000000000000000000000836001900416119050919050565b6000807f4000000000000000000000000000000000000000000000000000000000000000836001900416119050919050565b600080836001029050600360008281526020019081526020016000205460019004915060008203611f3257600080fd5b7fffffffffffffffffffffffff0000000000000000000000000000000000000000821691508273ffffffffffffffffffffffffffffffffffffffff168217915081600102600360008381526020019081526020016000208190555050505050565b6040518060600160405280600065ffffffffffff168152602001600065ffffffffffff168152602001600065ffffffffffff1681525090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61201581611fe0565b811461202057600080fd5b50565b6000813590506120328161200c565b92915050565b60006020828403121561204e5761204d611fd6565b5b600061205c84828501612023565b91505092915050565b60008115159050919050565b61207a81612065565b82525050565b60006020820190506120956000830184612071565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156120d55780820151818401526020810190506120ba565b60008484015250505050565b6000601f19601f8301169050919050565b60006120fd8261209b565b61210781856120a6565b93506121178185602086016120b7565b612120816120e1565b840191505092915050565b6000602082019050818103600083015261214581846120f2565b905092915050565b6000819050919050565b6121608161214d565b811461216b57600080fd5b50565b60008135905061217d81612157565b92915050565b60006020828403121561219957612198611fd6565b5b60006121a78482850161216e565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006121db826121b0565b9050919050565b6121eb816121d0565b82525050565b600060208201905061220660008301846121e2565b92915050565b612215816121d0565b811461222057600080fd5b50565b6000813590506122328161220c565b92915050565b60008060006060848603121561225157612250611fd6565b5b600061225f86828701612223565b935050602061227086828701612223565b92505060406122818682870161216e565b9150509250925092565b6000819050919050565b61229e8161228b565b81146122a957600080fd5b50565b6000813590506122bb81612295565b92915050565b6000602082840312156122d7576122d6611fd6565b5b60006122e5848285016122ac565b91505092915050565b6122f78161228b565b82525050565b600060208201905061231260008301846122ee565b92915050565b60008060006060848603121561233157612330611fd6565b5b600061233f86828701612223565b9350506020612350868287016122ac565b92505060406123618682870161216e565b9150509250925092565b600065ffffffffffff82169050919050565b6123868161236b565b811461239157600080fd5b50565b6000813590506123a38161237d565b92915050565b600080604083850312156123c0576123bf611fd6565b5b60006123ce858286016122ac565b92505060206123df85828601612394565b9150509250929050565b60008060408385031215612400576123ff611fd6565b5b600061240e858286016122ac565b925050602061241f8582860161216e565b9150509250929050565b6124328161236b565b82525050565b600060608201905061244d6000830186612429565b61245a6020830185612429565b6124676040830184612429565b949350505050565b60006020828403121561248557612484611fd6565b5b600061249384828501612223565b91505092915050565b6124a58161214d565b82525050565b60006020820190506124c0600083018461249c565b92915050565b6124cf81612065565b81146124da57600080fd5b50565b6000813590506124ec816124c6565b92915050565b6000806040838503121561250957612508611fd6565b5b600061251785828601612223565b9250506020612528858286016124dd565b9150509250929050565b6000806040838503121561254957612548611fd6565b5b600061255785828601612223565b9250506020612568858286016122ac565b9150509250929050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6125b4826120e1565b810181811067ffffffffffffffff821117156125d3576125d261257c565b5b80604052505050565b60006125e6611fcc565b90506125f282826125ab565b919050565b600067ffffffffffffffff8211156126125761261161257c565b5b61261b826120e1565b9050602081019050919050565b82818337600083830152505050565b600061264a612645846125f7565b6125dc565b90508281526020810184848401111561266657612665612577565b5b612671848285612628565b509392505050565b600082601f83011261268e5761268d612572565b5b813561269e848260208601612637565b91505092915050565b600080600080608085870312156126c1576126c0611fd6565b5b60006126cf87828801612223565b94505060206126e087828801612223565b93505060406126f18782880161216e565b925050606085013567ffffffffffffffff81111561271257612711611fdb565b5b61271e87828801612679565b91505092959194509250565b60008060006060848603121561274357612742611fd6565b5b6000612751868287016122ac565b93505060206127628682870161216e565b92505060406127738682870161216e565b9150509250925092565b6000819050919050565b6127908161277d565b82525050565b60006020820190506127ab6000830184612787565b92915050565b600080604083850312156127c8576127c7611fd6565b5b60006127d685828601612223565b92505060206127e785828601612223565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061283857607f821691505b60208210810361284b5761284a6127f1565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006128ba8261236b565b91506128c58361236b565b9250828201905065ffffffffffff8111156128e3576128e2612880565b5b92915050565b60006128f48261214d565b91506128ff8361214d565b925082820390508181111561291757612916612880565b5b92915050565b60006129288261214d565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361295a57612959612880565b5b600182019050919050565b60008151905061297481612295565b92915050565b6000602082840312156129905761298f611fd6565b5b600061299e84828501612965565b91505092915050565b600060ff82169050919050565b60006129bf826129a7565b91506129ca836129a7565b9250828201905060ff8111156129e3576129e2612880565b5b92915050565b60006129f48261214d565b91506129ff8361214d565b9250828201905080821115612a1757612a16612880565b5b92915050565b600081519050612a2c8161220c565b92915050565b600060208284031215612a4857612a47611fd6565b5b6000612a5684828501612a1d565b9150509291505056fea2646970667358221220864133f500ab4d9c75ce5c8b482d64744a21d2c81982fc7b1665a1a51a1d089764736f6c63430008110033 +\ No newline at end of file diff --git a/python/eth_craft_nft/data/CraftNFT.json b/python/eth_craft_nft/data/CraftNFT.json @@ -1 +1 @@ -[{"inputs":[{"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":"_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":"bytes32","name":"content","type":"bytes32"},{"internalType":"uint48","name":"count","type":"uint48"}],"name":"allocate","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_content","type":"bytes32"},{"internalType":"uint256","name":"_superIndex","type":"uint256"},{"internalType":"uint256","name":"_startAt","type":"uint256"}],"name":"batchOf","outputs":[{"internalType":"int256","name":"","type":"int256"}],"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":"bytes32","name":"_truncatedId","type":"bytes32"}],"name":"getDigest","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_tokenContent","type":"bytes32"}],"name":"isActiveContent","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":"_recipient","type":"address"},{"internalType":"bytes32","name":"_content","type":"bytes32"},{"internalType":"uint256","name":"_batch","type":"uint256"}],"name":"mintFromBatchTo","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_recipient","type":"address"},{"internalType":"bytes32","name":"_content","type":"bytes32"}],"name":"mintTo","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"mintedToken","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"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":"toURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"token","outputs":[{"internalType":"uint48","name":"count","type":"uint48"},{"internalType":"uint48","name":"cumulativeCount","type":"uint48"},{"internalType":"uint48","name":"cursor","type":"uint48"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokens","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"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":"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":"_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":"bytes32","name":"content","type":"bytes32"},{"internalType":"uint48","name":"count","type":"uint48"}],"name":"allocate","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_content","type":"bytes32"},{"internalType":"uint256","name":"_superIndex","type":"uint256"},{"internalType":"uint256","name":"_startAt","type":"uint256"}],"name":"batchOf","outputs":[{"internalType":"int256","name":"","type":"int256"}],"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":"bytes32","name":"_truncatedId","type":"bytes32"}],"name":"getDigest","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"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":"_recipient","type":"address"},{"internalType":"bytes32","name":"_content","type":"bytes32"},{"internalType":"uint256","name":"_batch","type":"uint256"}],"name":"mintFromBatchTo","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_recipient","type":"address"},{"internalType":"bytes32","name":"_content","type":"bytes32"}],"name":"mintTo","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"mintedToken","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"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":"toURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"token","outputs":[{"internalType":"uint48","name":"count","type":"uint48"},{"internalType":"uint48","name":"cumulativeCount","type":"uint48"},{"internalType":"uint48","name":"cursor","type":"uint48"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokens","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"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"}] diff --git a/python/eth_craft_nft/nft.py b/python/eth_craft_nft/nft.py @@ -131,6 +131,23 @@ class CraftNFT(ERC721): return o + def get_digest(self, contract_address, token_id, sender_address=ZERO_ADDRESS, id_generator=None): + j = JSONRPCRequest(id_generator) + o = j.template() + o['method'] = 'eth_call' + enc = ABIContractEncoder() + enc.method('getDigest') + enc.typ(ABIContractType.BYTES32) + enc.bytes32(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') + o = j.finalize(o) + return o + + def mint_to(self, contract_address, sender_address, recipient, token_id, batch, tx_format=TxFormat.JSONRPC): enc = ABIContractEncoder() enc.method('mintFromBatchTo') diff --git a/python/tests/test_basic.py b/python/tests/test_basic.py @@ -301,5 +301,93 @@ class Test(EthTesterCase): self.assertEqual(r['status'], 0) + def test_digest_single(self): + nonce_oracle = RPCNonceOracle(self.accounts[0], self.rpc) + c = CraftNFT(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) + (tx_hash_hex, o) = c.allocate(self.address, self.accounts[0], hash_of_foo) + self.rpc.do(o) + + (tx_hash_hex, o) = c.mint_to(self.address, self.accounts[0], self.accounts[1], hash_of_foo, 0) + self.rpc.do(o) + + o = c.get_token_raw(self.address, hash_of_foo, sender_address=self.accounts[0]) + r = self.rpc.do(o) + + o = c.get_digest(self.address, hash_of_foo, sender_address=self.accounts[0]) + r = self.rpc.do(o) + self.assertEqual(strip_0x(r), hash_of_foo) + + + + def test_digest_batch(self): + nonce_oracle = RPCNonceOracle(self.accounts[0], self.rpc) + c = CraftNFT(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) + (tx_hash_hex, o) = c.allocate(self.address, self.accounts[0], hash_of_foo, amount=2) + self.rpc.do(o) + + (tx_hash_hex, o) = c.allocate(self.address, self.accounts[0], hash_of_foo, amount=3) + self.rpc.do(o) + + (tx_hash_hex, o) = c.mint_to(self.address, self.accounts[0], self.accounts[1], hash_of_foo, 0) + self.rpc.do(o) + + (tx_hash_hex, o) = c.mint_to(self.address, self.accounts[0], self.accounts[1], hash_of_foo, 1) + self.rpc.do(o) + + (tx_hash_hex, o) = c.mint_to(self.address, self.accounts[0], self.accounts[1], hash_of_foo, 1) + self.rpc.do(o) + + expected_id = hash_of_foo[:64-10] + '0000000000' + o = c.get_token_raw(self.address, expected_id, sender_address=self.accounts[0]) + r = self.rpc.do(o) + + o = c.get_digest(self.address, expected_id, sender_address=self.accounts[0]) + r = self.rpc.do(o) + self.assertEqual(strip_0x(r), hash_of_foo) + + expected_id = hash_of_foo[:64-10] + '0000100000' + o = c.get_digest(self.address, expected_id, sender_address=self.accounts[0]) + r = self.rpc.do(o) + self.assertEqual(strip_0x(r), hash_of_foo) + + expected_id = hash_of_foo[:64-10] + '0000100001' + o = c.get_digest(self.address, expected_id, sender_address=self.accounts[0]) + r = self.rpc.do(o) + self.assertEqual(strip_0x(r), hash_of_foo) + + + def test_token_uri(self): + nonce_oracle = RPCNonceOracle(self.accounts[0], self.rpc) + c = CraftNFT(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) + (tx_hash_hex, o) = c.allocate(self.address, self.accounts[0], hash_of_foo) + self.rpc.do(o) + + (tx_hash_hex, o) = c.mint_to(self.address, self.accounts[0], self.accounts[1], hash_of_foo, 0) + self.rpc.do(o) + + o = c.token_uri(self.address, int(hash_of_foo, 16), sender_address=self.accounts[0]) + r = self.rpc.do(o) + uri = c.parse_token_uri(r) + + self.assertEqual('sha256:' + hash_of_foo, uri) + + + def test_token_uri_batch(self): + nonce_oracle = RPCNonceOracle(self.accounts[0], self.rpc) + c = CraftNFT(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) + (tx_hash_hex, o) = c.allocate(self.address, self.accounts[0], hash_of_foo, amount=2) + self.rpc.do(o) + + (tx_hash_hex, o) = c.mint_to(self.address, self.accounts[0], self.accounts[1], hash_of_foo, 0) + self.rpc.do(o) + + expected_id = hash_of_foo[:64-10] + '0000000000' + o = c.token_uri(self.address, int(expected_id, 16), sender_address=self.accounts[0]) + r = self.rpc.do(o) + uri = c.parse_token_uri(r) + + self.assertEqual('sha256:' + hash_of_foo, uri) + + if __name__ == '__main__': unittest.main() diff --git a/solidity/CraftNFT.sol b/solidity/CraftNFT.sol @@ -37,18 +37,27 @@ contract CraftNFT { symbol = _symbol; } - function isActiveContent(bytes32 _tokenContent) public view returns(bool) { + function isActive(bytes32 _tokenContent) private view returns(bool) { return uint256(_tokenContent) & 0x8000000000000000000000000000000000000000000000000000000000000000 > 0; } + function isSingle(bytes32 _tokenContent) private view returns(bool) { + return uint256(_tokenContent) & 0x4000000000000000000000000000000000000000000000000000000000000000 > 0; + } + function getDigest(bytes32 _truncatedId) public view returns (bytes32) { bytes32 digest; digest = mintedToken[_truncatedId]; - require(isActiveContent(digest)); + require(isActive(digest)); - digest >>= 160; - digest |= _truncatedId & 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000; + if (isSingle(digest)) { + return _truncatedId; + } + + digest &= 0x00ffffffffff0000000000000000000000000000000000000000000000000000; + digest >>= 208; + digest |= _truncatedId & 0xffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000; return digest; } @@ -84,7 +93,7 @@ contract CraftNFT { require(mintedToken[_content] == bytes32(0x00)); right = uint160(_recipient); - right |= (1 << 255); + right |= (3 << 254); mintedToken[_content] = bytes32(right); return _content; @@ -116,13 +125,13 @@ contract CraftNFT { } require(spec.cursor < spec.count); - right = uint256(_content) & ((1 << 48) - 1); - right <<= 200; + right = uint256(_content) & ((1 << 40) - 1); + right <<= 208; right |= (1 << 255); right |= uint160(_recipient); left = uint256(_content) & 0xffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000; - left |= (_batch << 40); + left |= (_batch << 20); left |= spec.cursor; spec.cursor += 1;