diff --git a/x/evm/contracts/counter/Counter.go b/x/evm/contracts/counter/Counter.go index 2d2ee11..9453446 100644 --- a/x/evm/contracts/counter/Counter.go +++ b/x/evm/contracts/counter/Counter.go @@ -31,8 +31,8 @@ var ( // CounterMetaData contains all meta data concerning the Counter contract. var CounterMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldCount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newCount\",\"type\":\"uint256\"}],\"name\":\"increased\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"count\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"n\",\"type\":\"uint64\"}],\"name\":\"get_blockhash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"callback_id\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"name\":\"ibc_ack\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"callback_id\",\"type\":\"uint64\"}],\"name\":\"ibc_timeout\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"increase\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"path\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"req\",\"type\":\"string\"}],\"name\":\"query_cosmos\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"result\",\"type\":\"string\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x6080604052610861806100115f395ff3fe608060405260043610610054575f3560e01c806306661abd146100585780630d4f1f9d1461008257806331a503f0146100aa578063ac7fde5f146100d2578063cad235541461010e578063e8927fbc1461014a575b5f80fd5b348015610063575f80fd5b5061006c610154565b60405161007991906102d8565b60405180910390f35b34801561008d575f80fd5b506100a860048036038101906100a39190610374565b610159565b005b3480156100b5575f80fd5b506100d060048036038101906100cb91906103b2565b6101a0565b005b3480156100dd575f80fd5b506100f860048036038101906100f391906103b2565b6101c4565b60405161010591906103f5565b60405180910390f35b348015610119575f80fd5b50610134600480360381019061012f919061054a565b6101d8565b6040516101419190610620565b60405180910390f35b610152610261565b005b5f5481565b8015610185578167ffffffffffffffff165f80828254610179919061066d565b9250508190555061019c565b5f80815480929190610196906106a0565b91905055505b5050565b8067ffffffffffffffff165f808282546101ba919061066d565b9250508190555050565b5f8167ffffffffffffffff16409050919050565b606060f173ffffffffffffffffffffffffffffffffffffffff1663cad2355484846040518363ffffffff1660e01b81526004016102169291906106e7565b5f604051808303815f875af1158015610231573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f82011682018060405250810190610259919061078a565b905092915050565b5f80815480929190610272906106a0565b91905055507f61996fe196f72cb598c483e896a1221263a28bb630480aa89495f737d4a8e3df60015f546102a691906107d1565b5f546040516102b6929190610804565b60405180910390a1565b5f819050919050565b6102d2816102c0565b82525050565b5f6020820190506102eb5f8301846102c9565b92915050565b5f604051905090565b5f80fd5b5f80fd5b5f67ffffffffffffffff82169050919050565b61031e81610302565b8114610328575f80fd5b50565b5f8135905061033981610315565b92915050565b5f8115159050919050565b6103538161033f565b811461035d575f80fd5b50565b5f8135905061036e8161034a565b92915050565b5f806040838503121561038a576103896102fa565b5b5f6103978582860161032b565b92505060206103a885828601610360565b9150509250929050565b5f602082840312156103c7576103c66102fa565b5b5f6103d48482850161032b565b91505092915050565b5f819050919050565b6103ef816103dd565b82525050565b5f6020820190506104085f8301846103e6565b92915050565b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b61045c82610416565b810181811067ffffffffffffffff8211171561047b5761047a610426565b5b80604052505050565b5f61048d6102f1565b90506104998282610453565b919050565b5f67ffffffffffffffff8211156104b8576104b7610426565b5b6104c182610416565b9050602081019050919050565b828183375f83830152505050565b5f6104ee6104e98461049e565b610484565b90508281526020810184848401111561050a57610509610412565b5b6105158482856104ce565b509392505050565b5f82601f8301126105315761053061040e565b5b81356105418482602086016104dc565b91505092915050565b5f80604083850312156105605761055f6102fa565b5b5f83013567ffffffffffffffff81111561057d5761057c6102fe565b5b6105898582860161051d565b925050602083013567ffffffffffffffff8111156105aa576105a96102fe565b5b6105b68582860161051d565b9150509250929050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f6105f2826105c0565b6105fc81856105ca565b935061060c8185602086016105da565b61061581610416565b840191505092915050565b5f6020820190508181035f83015261063881846105e8565b905092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f610677826102c0565b9150610682836102c0565b925082820190508082111561069a57610699610640565b5b92915050565b5f6106aa826102c0565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036106dc576106db610640565b5b600182019050919050565b5f6040820190508181035f8301526106ff81856105e8565b9050818103602083015261071381846105e8565b90509392505050565b5f61072e6107298461049e565b610484565b90508281526020810184848401111561074a57610749610412565b5b6107558482856105da565b509392505050565b5f82601f8301126107715761077061040e565b5b815161078184826020860161071c565b91505092915050565b5f6020828403121561079f5761079e6102fa565b5b5f82015167ffffffffffffffff8111156107bc576107bb6102fe565b5b6107c88482850161075d565b91505092915050565b5f6107db826102c0565b91506107e6836102c0565b92508282039050818111156107fe576107fd610640565b5b92915050565b5f6040820190506108175f8301856102c9565b61082460208301846102c9565b939250505056fea2646970667358221220edf83c9869e7b1f6b208a0b95c5ff4dc0d6020752d0251d1ccb8b12b3d8fabfd64736f6c63430008190033", + ABI: "[{\"inputs\":[],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"length\",\"type\":\"uint256\"}],\"name\":\"StringsInsufficientHexLength\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldCount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newCount\",\"type\":\"uint256\"}],\"name\":\"increased\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"count\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"n\",\"type\":\"uint64\"}],\"name\":\"get_blockhash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"callback_id\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"name\":\"ibc_ack\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"callback_id\",\"type\":\"uint64\"}],\"name\":\"ibc_timeout\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"increase\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"path\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"req\",\"type\":\"string\"}],\"name\":\"query_cosmos\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"result\",\"type\":\"string\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"n\",\"type\":\"uint64\"}],\"name\":\"recursive\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x6080604052611587806100115f395ff3fe60806040526004361061006f575f3560e01c8063619368951161004d57806361936895146100ed578063ac7fde5f14610115578063cad2355414610151578063e8927fbc1461018d5761006f565b806306661abd146100735780630d4f1f9d1461009d57806331a503f0146100c5575b5f80fd5b34801561007e575f80fd5b50610087610197565b60405161009491906109c8565b60405180910390f35b3480156100a8575f80fd5b506100c360048036038101906100be9190610a64565b61019c565b005b3480156100d0575f80fd5b506100eb60048036038101906100e69190610aa2565b6101e3565b005b3480156100f8575f80fd5b50610113600480360381019061010e9190610aa2565b610207565b005b348015610120575f80fd5b5061013b60048036038101906101369190610aa2565b610323565b6040516101489190610ae5565b60405180910390f35b34801561015c575f80fd5b5061017760048036038101906101729190610c3a565b610337565b6040516101849190610d10565b60405180910390f35b6101956103c0565b005b5f5481565b80156101c8578167ffffffffffffffff165f808282546101bc9190610d5d565b925050819055506101df565b5f808154809291906101d990610d90565b91905055505b5050565b8067ffffffffffffffff165f808282546101fd9190610d5d565b9250508190555050565b5f8167ffffffffffffffff1603156103205760f173ffffffffffffffffffffffffffffffffffffffff1663d46f64e661023f8361041f565b6040518263ffffffff1660e01b815260040161025b9190610d10565b6020604051808303815f875af1158015610277573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061029b9190610deb565b5060f173ffffffffffffffffffffffffffffffffffffffff1663d46f64e66102c28361041f565b6040518263ffffffff1660e01b81526004016102de9190610d10565b6020604051808303815f875af11580156102fa573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061031e9190610deb565b505b50565b5f8167ffffffffffffffff16409050919050565b606060f173ffffffffffffffffffffffffffffffffffffffff1663cad2355484846040518363ffffffff1660e01b8152600401610375929190610e16565b5f604051808303815f875af1158015610390573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f820116820180604052508101906103b89190610eb9565b905092915050565b5f808154809291906103d190610d90565b91905055507f61996fe196f72cb598c483e896a1221263a28bb630480aa89495f737d4a8e3df60015f546104059190610f00565b5f54604051610415929190610f33565b60405180910390a1565b606060f173ffffffffffffffffffffffffffffffffffffffff16636af32a55306040518263ffffffff1660e01b815260040161045b9190610f99565b5f604051808303815f875af1158015610476573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f8201168201806040525081019061049e9190610eb9565b6104a73061052b565b610503636193689560e01b6001866104bf9190610fb2565b6040516020016104cf9190610ffc565b6040516020818303038152906040526040516020016104ef9291906110a4565b604051602081830303815290604052610558565b60405160200161051593929190611331565b6040516020818303038152906040529050919050565b60606105518273ffffffffffffffffffffffffffffffffffffffff16601460ff16610772565b9050919050565b60605f6002835161056991906113c4565b67ffffffffffffffff81111561058257610581610b16565b5b6040519080825280601f01601f1916602001820160405280156105b45781602001600182028036833780820191505090505b5090505f6040518060400160405280601081526020017f303132333435363738396162636465660000000000000000000000000000000081525090505f5b84518110156107485781825186838151811061061157610610611405565b5b602001015160f81c60f81b60f81c60ff1661062c919061145f565b8151811061063d5761063c611405565b5b602001015160f81c60f81b8360028361065691906113c4565b8151811061066757610666611405565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053508182518683815181106106ab576106aa611405565b5b602001015160f81c60f81b60f81c60ff166106c6919061148f565b815181106106d7576106d6611405565b5b602001015160f81c60f81b8360016002846106f291906113c4565b6106fc9190610d5d565b8151811061070d5761070c611405565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a90535080806001019150506105f2565b508160405160200161075a9190611509565b60405160208183030381529060405292505050919050565b60605f8390505f600284600261078891906113c4565b6107929190610d5d565b67ffffffffffffffff8111156107ab576107aa610b16565b5b6040519080825280601f01601f1916602001820160405280156107dd5781602001600182028036833780820191505090505b5090507f3000000000000000000000000000000000000000000000000000000000000000815f8151811061081457610813611405565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053507f78000000000000000000000000000000000000000000000000000000000000008160018151811061087757610876611405565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053505f60018560026108b591906113c4565b6108bf9190610d5d565b90505b600181111561095e577f3031323334353637383961626364656600000000000000000000000000000000600f84166010811061090157610900611405565b5b1a60f81b82828151811061091857610917611405565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a905350600483901c9250806109579061152a565b90506108c2565b505f82146109a55784846040517fe22e27eb00000000000000000000000000000000000000000000000000000000815260040161099c929190610f33565b60405180910390fd5b809250505092915050565b5f819050919050565b6109c2816109b0565b82525050565b5f6020820190506109db5f8301846109b9565b92915050565b5f604051905090565b5f80fd5b5f80fd5b5f67ffffffffffffffff82169050919050565b610a0e816109f2565b8114610a18575f80fd5b50565b5f81359050610a2981610a05565b92915050565b5f8115159050919050565b610a4381610a2f565b8114610a4d575f80fd5b50565b5f81359050610a5e81610a3a565b92915050565b5f8060408385031215610a7a57610a796109ea565b5b5f610a8785828601610a1b565b9250506020610a9885828601610a50565b9150509250929050565b5f60208284031215610ab757610ab66109ea565b5b5f610ac484828501610a1b565b91505092915050565b5f819050919050565b610adf81610acd565b82525050565b5f602082019050610af85f830184610ad6565b92915050565b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b610b4c82610b06565b810181811067ffffffffffffffff82111715610b6b57610b6a610b16565b5b80604052505050565b5f610b7d6109e1565b9050610b898282610b43565b919050565b5f67ffffffffffffffff821115610ba857610ba7610b16565b5b610bb182610b06565b9050602081019050919050565b828183375f83830152505050565b5f610bde610bd984610b8e565b610b74565b905082815260208101848484011115610bfa57610bf9610b02565b5b610c05848285610bbe565b509392505050565b5f82601f830112610c2157610c20610afe565b5b8135610c31848260208601610bcc565b91505092915050565b5f8060408385031215610c5057610c4f6109ea565b5b5f83013567ffffffffffffffff811115610c6d57610c6c6109ee565b5b610c7985828601610c0d565b925050602083013567ffffffffffffffff811115610c9a57610c996109ee565b5b610ca685828601610c0d565b9150509250929050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f610ce282610cb0565b610cec8185610cba565b9350610cfc818560208601610cca565b610d0581610b06565b840191505092915050565b5f6020820190508181035f830152610d288184610cd8565b905092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f610d67826109b0565b9150610d72836109b0565b9250828201905080821115610d8a57610d89610d30565b5b92915050565b5f610d9a826109b0565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610dcc57610dcb610d30565b5b600182019050919050565b5f81519050610de581610a3a565b92915050565b5f60208284031215610e0057610dff6109ea565b5b5f610e0d84828501610dd7565b91505092915050565b5f6040820190508181035f830152610e2e8185610cd8565b90508181036020830152610e428184610cd8565b90509392505050565b5f610e5d610e5884610b8e565b610b74565b905082815260208101848484011115610e7957610e78610b02565b5b610e84848285610cca565b509392505050565b5f82601f830112610ea057610e9f610afe565b5b8151610eb0848260208601610e4b565b91505092915050565b5f60208284031215610ece57610ecd6109ea565b5b5f82015167ffffffffffffffff811115610eeb57610eea6109ee565b5b610ef784828501610e8c565b91505092915050565b5f610f0a826109b0565b9150610f15836109b0565b9250828203905081811115610f2d57610f2c610d30565b5b92915050565b5f604082019050610f465f8301856109b9565b610f5360208301846109b9565b9392505050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f610f8382610f5a565b9050919050565b610f9381610f79565b82525050565b5f602082019050610fac5f830184610f8a565b92915050565b5f610fbc826109f2565b9150610fc7836109f2565b9250828203905067ffffffffffffffff811115610fe757610fe6610d30565b5b92915050565b610ff6816109f2565b82525050565b5f60208201905061100f5f830184610fed565b92915050565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b5f819050919050565b61105a61105582611015565b611040565b82525050565b5f81519050919050565b5f81905092915050565b5f61107e82611060565b611088818561106a565b9350611098818560208601610cca565b80840191505092915050565b5f6110af8285611049565b6004820191506110bf8284611074565b91508190509392505050565b5f81905092915050565b7f7b224074797065223a20222f6d696e6965766d2e65766d2e76312e4d736743615f8201527f6c6c222c00000000000000000000000000000000000000000000000000000000602082015250565b5f61112f6024836110cb565b915061113a826110d5565b602482019050919050565b7f2273656e646572223a20220000000000000000000000000000000000000000005f82015250565b5f611179600b836110cb565b915061118482611145565b600b82019050919050565b5f61119982610cb0565b6111a381856110cb565b93506111b3818560208601610cca565b80840191505092915050565b7f222c0000000000000000000000000000000000000000000000000000000000005f82015250565b5f6111f36002836110cb565b91506111fe826111bf565b600282019050919050565b7f22636f6e74726163745f61646472223a202200000000000000000000000000005f82015250565b5f61123d6012836110cb565b915061124882611209565b601282019050919050565b7f22696e707574223a2022000000000000000000000000000000000000000000005f82015250565b5f611287600a836110cb565b915061129282611253565b600a82019050919050565b7f2276616c7565223a202230222c000000000000000000000000000000000000005f82015250565b5f6112d1600d836110cb565b91506112dc8261129d565b600d82019050919050565b7f226163636573735f6c697374223a205b5d7d00000000000000000000000000005f82015250565b5f61131b6012836110cb565b9150611326826112e7565b601282019050919050565b5f61133b82611123565b91506113468261116d565b9150611352828661118f565b915061135d826111e7565b915061136882611231565b9150611374828561118f565b915061137f826111e7565b915061138a8261127b565b9150611396828461118f565b91506113a1826111e7565b91506113ac826112c5565b91506113b78261130f565b9150819050949350505050565b5f6113ce826109b0565b91506113d9836109b0565b92508282026113e7816109b0565b915082820484148315176113fe576113fd610d30565b5b5092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f611469826109b0565b9150611474836109b0565b92508261148457611483611432565b5b828204905092915050565b5f611499826109b0565b91506114a4836109b0565b9250826114b4576114b3611432565b5b828206905092915050565b7f30780000000000000000000000000000000000000000000000000000000000005f82015250565b5f6114f36002836110cb565b91506114fe826114bf565b600282019050919050565b5f611513826114e7565b915061151f8284611074565b915081905092915050565b5f611534826109b0565b91505f820361154657611545610d30565b5b60018203905091905056fea264697066735822122003a87b734bd35a936996432aff9fc8fda480bd66b57c6ab073a8e8ed245289bd64736f6c63430008190033", } // CounterABI is the input ABI used to generate the binding from. @@ -348,6 +348,27 @@ func (_Counter *CounterTransactorSession) QueryCosmos(path string, req string) ( return _Counter.Contract.QueryCosmos(&_Counter.TransactOpts, path, req) } +// Recursive is a paid mutator transaction binding the contract method 0x61936895. +// +// Solidity: function recursive(uint64 n) returns() +func (_Counter *CounterTransactor) Recursive(opts *bind.TransactOpts, n uint64) (*types.Transaction, error) { + return _Counter.contract.Transact(opts, "recursive", n) +} + +// Recursive is a paid mutator transaction binding the contract method 0x61936895. +// +// Solidity: function recursive(uint64 n) returns() +func (_Counter *CounterSession) Recursive(n uint64) (*types.Transaction, error) { + return _Counter.Contract.Recursive(&_Counter.TransactOpts, n) +} + +// Recursive is a paid mutator transaction binding the contract method 0x61936895. +// +// Solidity: function recursive(uint64 n) returns() +func (_Counter *CounterTransactorSession) Recursive(n uint64) (*types.Transaction, error) { + return _Counter.Contract.Recursive(&_Counter.TransactOpts, n) +} + // CounterIncreasedIterator is returned from FilterIncreased and is used to iterate over the raw logs and unpacked data for Increased events raised by the Counter contract. type CounterIncreasedIterator struct { Event *CounterIncreased // Event containing the contract specifics and raw log diff --git a/x/evm/contracts/counter/Counter.sol b/x/evm/contracts/counter/Counter.sol index ea94720..0eeedd1 100644 --- a/x/evm/contracts/counter/Counter.sol +++ b/x/evm/contracts/counter/Counter.sol @@ -3,6 +3,7 @@ pragma solidity ^0.8.24; import "../i_ibc_async_callback/IIBCAsyncCallback.sol"; import "../i_cosmos/ICosmos.sol"; +import "../strings/Strings.sol"; contract Counter is IIBCAsyncCallback { uint256 public count; @@ -39,4 +40,36 @@ contract Counter is IIBCAsyncCallback { function get_blockhash(uint64 n) external view returns (bytes32) { return blockhash(n); } + + function recursive(uint64 n) public { + if (n == 0) { + return; + } + + COSMOS_CONTRACT.execute_cosmos(_recursive(n)); + + // to test branching + COSMOS_CONTRACT.execute_cosmos(_recursive(n)); + } + + function _recursive(uint64 n) internal returns (string memory message) { + message = string( + abi.encodePacked( + '{"@type": "/minievm.evm.v1.MsgCall",', + '"sender": "', + COSMOS_CONTRACT.to_cosmos_address(address(this)), + '",', + '"contract_addr": "', + Strings.toHexString(address(this)), + '",', + '"input": "', + Strings.toHexString( + abi.encodePacked(this.recursive.selector, abi.encode(n - 1)) + ), + '",', + '"value": "0",', + '"access_list": []}' + ) + ); + } } diff --git a/x/evm/contracts/erc20_wrapper/ERC20Wrapper.go b/x/evm/contracts/erc20_wrapper/ERC20Wrapper.go index 9e46d02..51e4bc9 100644 --- a/x/evm/contracts/erc20_wrapper/ERC20Wrapper.go +++ b/x/evm/contracts/erc20_wrapper/ERC20Wrapper.go @@ -32,7 +32,7 @@ var ( // Erc20WrapperMetaData contains all meta data concerning the Erc20Wrapper contract. var Erc20WrapperMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"erc20Factory\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"length\",\"type\":\"uint256\"}],\"name\":\"StringsInsufficientHexLength\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"erc20\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"ERC20Created\",\"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\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol\",\"type\":\"string\"},{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"}],\"name\":\"createERC20\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"factory\",\"outputs\":[{\"internalType\":\"contractERC20Factory\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"callback_id\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"name\":\"ibc_ack\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"callback_id\",\"type\":\"uint64\"}],\"name\":\"ibc_timeout\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"originTokens\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"wrappedTokenDenom\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"wrappedAmt\",\"type\":\"uint256\"}],\"name\":\"unwrap\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"channel\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"receiver\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"timeout\",\"type\":\"uint256\"}],\"name\":\"wrap\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"wrappedTokens\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x60a06040525f8060146101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550348015610037575f80fd5b5060405161520e38038061520e83398181016040528101906100599190610130565b335f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff16815250505061015b565b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6100ff826100d6565b9050919050565b61010f816100f5565b8114610119575f80fd5b50565b5f8151905061012a81610106565b92915050565b5f60208284031215610145576101446100d2565b5b5f6101528482850161011c565b91505092915050565b60805161509461017a5f395f8181610935015261101501526150945ff3fe608060405234801561000f575f80fd5b50600436106100a7575f3560e01c80639a1114321161006f5780639a11143214610161578063b5ad1fb61461017d578063c45a0155146101ad578063d5c6b504146101cb578063f2fde38b146101fb578063fc07875814610217576100a7565b806301ffc9a7146100ab57806306ef1a86146100db5780630d4f1f9d1461010b57806331a503f0146101275780638da5cb5b14610143575b5f80fd5b6100c560048036038101906100c09190611a72565b610233565b6040516100d29190611ab7565b60405180910390f35b6100f560048036038101906100f09190611c42565b61029c565b6040516101029190611d09565b60405180910390f35b61012560048036038101906101209190611d89565b61041b565b005b610141600480360381019061013c9190611dc7565b61042e565b005b61014b61043a565b6040516101589190611d09565b60405180910390f35b61017b60048036038101906101769190611e4f565b61045d565b005b61019760048036038101906101929190611efe565b610903565b6040516101a49190611d09565b60405180910390f35b6101b5610933565b6040516101c29190611f84565b60405180910390f35b6101e560048036038101906101e09190611efe565b610957565b6040516101f29190611d09565b60405180910390f35b61021560048036038101906102109190611efe565b610987565b005b610231600480360381019061022c9190611f9d565b610acf565b005b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b5f808484846040516102ad906119ff565b6102b993929190612078565b604051809103905ff0801580156102d2573d5f803e3d5ffd5b50905060f273ffffffffffffffffffffffffffffffffffffffff1663d126274a826040518263ffffffff1660e01b815260040161030f9190611d09565b6020604051808303815f875af115801561032b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061034f91906120cf565b508073ffffffffffffffffffffffffffffffffffffffff1663f2fde38b336040518263ffffffff1660e01b81526004016103899190611d09565b5f604051808303815f87803b1580156103a0575f80fd5b505af11580156103b2573d5f803e3d5ffd5b505050503373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f85e892981b234101136bc30081e0a5c44345bebc0940193230c20a43b279e2d160405160405180910390a3809150509392505050565b8061042a5761042982610e48565b5b5050565b61043781610e48565b50565b5f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b61046684610f83565b8373ffffffffffffffffffffffffffffffffffffffff166323b872dd3330856040518463ffffffff1660e01b81526004016104a393929190612109565b6020604051808303815f875af11580156104bf573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104e391906120cf565b505f61055d838673ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610532573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105569190612152565b6006611338565b905060015f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166340c10f1930836040518363ffffffff1660e01b81526004016105f692919061217d565b5f604051808303815f87803b15801561060d575f80fd5b505af115801561061f573d5f803e3d5ffd5b5050505060015f60148282829054906101000a900467ffffffffffffffff1661064891906121d1565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060405180606001604052803373ffffffffffffffffffffffffffffffffffffffff16815260200160f173ffffffffffffffffffffffffffffffffffffffff166381cf0f6a60015f8a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518263ffffffff1660e01b815260040161072b9190611d09565b5f604051808303815f875af1158015610746573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f8201168201806040525081019061076e919061227a565b81526020018281525060035f8060149054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff1681526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550602082015181600101908161080a91906124b2565b506040820151816002015590505060f173ffffffffffffffffffffffffffffffffffffffff1663d46f64e661089e8860015f8a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1685878a611407565b6040518263ffffffff1660e01b81526004016108ba9190612581565b6020604051808303815f875af11580156108d6573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108fa91906120cf565b50505050505050565b6002602052805f5260405f205f915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b7f000000000000000000000000000000000000000000000000000000000000000081565b6001602052805f5260405f205f915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146109dd575f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610a14575f80fd5b8073ffffffffffffffffffffffffffffffffffffffff165f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3805f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b5f60f173ffffffffffffffffffffffffffffffffffffffff16632b3324ce856040518263ffffffff1660e01b8152600401610b0a9190612581565b6020604051808303815f875af1158015610b26573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b4a91906125b5565b90505f73ffffffffffffffffffffffffffffffffffffffff1660025f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1603610c16576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c0d9061262a565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166379cc679033846040518363ffffffff1660e01b8152600401610c5192919061217d565b6020604051808303815f875af1158015610c6d573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c9191906120cf565b505f610d6783600660025f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d3e573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d629190612152565b611338565b905060025f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb85836040518363ffffffff1660e01b8152600401610e0092919061217d565b6020604051808303815f875af1158015610e1c573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e4091906120cf565b505050505050565b5f60035f8367ffffffffffffffff1667ffffffffffffffff1681526020019081526020015f206040518060600160405290815f82015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600182018054610edd906122ee565b80601f0160208091040260200160405190810160405280929190818152602001828054610f09906122ee565b8015610f545780601f10610f2b57610100808354040283529160200191610f54565b820191905f5260205f20905b815481529060010190602001808311610f3757829003601f168201915b505050505081526020016002820154815250509050610f7f8160200151825f01518360400151610acf565b5050565b5f73ffffffffffffffffffffffffffffffffffffffff1660015f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1603611335575f7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166306ef1a866040518060400160405280600781526020017f57726170706564000000000000000000000000000000000000000000000000008152508473ffffffffffffffffffffffffffffffffffffffff166306fdde036040518163ffffffff1660e01b81526004015f60405180830381865afa1580156110cd573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f820116820180604052508101906110f5919061227a565b604051602001611106929190612682565b6040516020818303038152906040526040518060400160405280600181526020017f57000000000000000000000000000000000000000000000000000000000000008152508573ffffffffffffffffffffffffffffffffffffffff166395d89b416040518163ffffffff1660e01b81526004015f60405180830381865afa158015611193573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f820116820180604052508101906111bb919061227a565b6040516020016111cc929190612682565b60405160208183030381529060405260066040518463ffffffff1660e01b81526004016111fb93929190612078565b6020604051808303815f875af1158015611217573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061123b91906125b5565b90508060015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508160025f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505b50565b5f8160ff168360ff161115611379575f828461135491906126a5565b60ff16600a6113639190612808565b90508085611371919061287f565b9150506113be565b8160ff168360ff1610156113b9575f838361139491906126a5565b60ff16600a6113a39190612808565b905080856113b191906128af565b9150506113bd565b8390505b5b5f8103611400576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113f79061293a565b60405180910390fd5b9392505050565b60608560f173ffffffffffffffffffffffffffffffffffffffff166381cf0f6a876040518263ffffffff1660e01b81526004016114449190611d09565b5f604051808303815f875af115801561145f573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f82011682018060405250810190611487919061227a565b61149086611579565b60f173ffffffffffffffffffffffffffffffffffffffff16636af32a55306040518263ffffffff1660e01b81526004016114ca9190611d09565b5f604051808303815f875af11580156114e5573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f8201168201806040525081019061150d919061227a565b8561151788611579565b61153f5f60149054906101000a900467ffffffffffffffff1667ffffffffffffffff16611579565b61154830611643565b60405160200161155f989796959493929190612e20565b604051602081830303815290604052905095945050505050565b60605f600161158784611670565b0190505f8167ffffffffffffffff8111156115a5576115a4611ae8565b5b6040519080825280601f01601f1916602001820160405280156115d75781602001600182028036833780820191505090505b5090505f82602001820190505b600115611638578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a858161162d5761162c612852565b5b0494505f85036115e4575b819350505050919050565b60606116698273ffffffffffffffffffffffffffffffffffffffff16601460ff166117c1565b9050919050565b5f805f90507a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083106116cc577a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083816116c2576116c1612852565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310611709576d04ee2d6d415b85acef810000000083816116ff576116fe612852565b5b0492506020810190505b662386f26fc10000831061173857662386f26fc10000838161172e5761172d612852565b5b0492506010810190505b6305f5e1008310611761576305f5e100838161175757611756612852565b5b0492506008810190505b612710831061178657612710838161177c5761177b612852565b5b0492506004810190505b606483106117a9576064838161179f5761179e612852565b5b0492506002810190505b600a83106117b8576001810190505b80915050919050565b60605f8390505f60028460026117d791906128af565b6117e19190612f6d565b67ffffffffffffffff8111156117fa576117f9611ae8565b5b6040519080825280601f01601f19166020018201604052801561182c5781602001600182028036833780820191505090505b5090507f3000000000000000000000000000000000000000000000000000000000000000815f8151811061186357611862612fa0565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053507f7800000000000000000000000000000000000000000000000000000000000000816001815181106118c6576118c5612fa0565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053505f600185600261190491906128af565b61190e9190612f6d565b90505b60018111156119ad577f3031323334353637383961626364656600000000000000000000000000000000600f8416601081106119505761194f612fa0565b5b1a60f81b82828151811061196757611966612fa0565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a905350600483901c9250806119a690612fcd565b9050611911565b505f82146119f45784846040517fe22e27eb0000000000000000000000000000000000000000000000000000000081526004016119eb929190612ff4565b60405180910390fd5b809250505092915050565b6120438061301c83390190565b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b611a5181611a1d565b8114611a5b575f80fd5b50565b5f81359050611a6c81611a48565b92915050565b5f60208284031215611a8757611a86611a15565b5b5f611a9484828501611a5e565b91505092915050565b5f8115159050919050565b611ab181611a9d565b82525050565b5f602082019050611aca5f830184611aa8565b92915050565b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b611b1e82611ad8565b810181811067ffffffffffffffff82111715611b3d57611b3c611ae8565b5b80604052505050565b5f611b4f611a0c565b9050611b5b8282611b15565b919050565b5f67ffffffffffffffff821115611b7a57611b79611ae8565b5b611b8382611ad8565b9050602081019050919050565b828183375f83830152505050565b5f611bb0611bab84611b60565b611b46565b905082815260208101848484011115611bcc57611bcb611ad4565b5b611bd7848285611b90565b509392505050565b5f82601f830112611bf357611bf2611ad0565b5b8135611c03848260208601611b9e565b91505092915050565b5f60ff82169050919050565b611c2181611c0c565b8114611c2b575f80fd5b50565b5f81359050611c3c81611c18565b92915050565b5f805f60608486031215611c5957611c58611a15565b5b5f84013567ffffffffffffffff811115611c7657611c75611a19565b5b611c8286828701611bdf565b935050602084013567ffffffffffffffff811115611ca357611ca2611a19565b5b611caf86828701611bdf565b9250506040611cc086828701611c2e565b9150509250925092565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f611cf382611cca565b9050919050565b611d0381611ce9565b82525050565b5f602082019050611d1c5f830184611cfa565b92915050565b5f67ffffffffffffffff82169050919050565b611d3e81611d22565b8114611d48575f80fd5b50565b5f81359050611d5981611d35565b92915050565b611d6881611a9d565b8114611d72575f80fd5b50565b5f81359050611d8381611d5f565b92915050565b5f8060408385031215611d9f57611d9e611a15565b5b5f611dac85828601611d4b565b9250506020611dbd85828601611d75565b9150509250929050565b5f60208284031215611ddc57611ddb611a15565b5b5f611de984828501611d4b565b91505092915050565b611dfb81611ce9565b8114611e05575f80fd5b50565b5f81359050611e1681611df2565b92915050565b5f819050919050565b611e2e81611e1c565b8114611e38575f80fd5b50565b5f81359050611e4981611e25565b92915050565b5f805f805f60a08688031215611e6857611e67611a15565b5b5f86013567ffffffffffffffff811115611e8557611e84611a19565b5b611e9188828901611bdf565b9550506020611ea288828901611e08565b945050604086013567ffffffffffffffff811115611ec357611ec2611a19565b5b611ecf88828901611bdf565b9350506060611ee088828901611e3b565b9250506080611ef188828901611e3b565b9150509295509295909350565b5f60208284031215611f1357611f12611a15565b5b5f611f2084828501611e08565b91505092915050565b5f819050919050565b5f611f4c611f47611f4284611cca565b611f29565b611cca565b9050919050565b5f611f5d82611f32565b9050919050565b5f611f6e82611f53565b9050919050565b611f7e81611f64565b82525050565b5f602082019050611f975f830184611f75565b92915050565b5f805f60608486031215611fb457611fb3611a15565b5b5f84013567ffffffffffffffff811115611fd157611fd0611a19565b5b611fdd86828701611bdf565b9350506020611fee86828701611e08565b9250506040611fff86828701611e3b565b9150509250925092565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f61203b82612009565b6120458185612013565b9350612055818560208601612023565b61205e81611ad8565b840191505092915050565b61207281611c0c565b82525050565b5f6060820190508181035f8301526120908186612031565b905081810360208301526120a48185612031565b90506120b36040830184612069565b949350505050565b5f815190506120c981611d5f565b92915050565b5f602082840312156120e4576120e3611a15565b5b5f6120f1848285016120bb565b91505092915050565b61210381611e1c565b82525050565b5f60608201905061211c5f830186611cfa565b6121296020830185611cfa565b61213660408301846120fa565b949350505050565b5f8151905061214c81611c18565b92915050565b5f6020828403121561216757612166611a15565b5b5f6121748482850161213e565b91505092915050565b5f6040820190506121905f830185611cfa565b61219d60208301846120fa565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f6121db82611d22565b91506121e683611d22565b9250828201905067ffffffffffffffff811115612206576122056121a4565b5b92915050565b5f61221e61221984611b60565b611b46565b90508281526020810184848401111561223a57612239611ad4565b5b612245848285612023565b509392505050565b5f82601f83011261226157612260611ad0565b5b815161227184826020860161220c565b91505092915050565b5f6020828403121561228f5761228e611a15565b5b5f82015167ffffffffffffffff8111156122ac576122ab611a19565b5b6122b88482850161224d565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061230557607f821691505b602082108103612318576123176122c1565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f6008830261237a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8261233f565b612384868361233f565b95508019841693508086168417925050509392505050565b5f6123b66123b16123ac84611e1c565b611f29565b611e1c565b9050919050565b5f819050919050565b6123cf8361239c565b6123e36123db826123bd565b84845461234b565b825550505050565b5f90565b6123f76123eb565b6124028184846123c6565b505050565b5b818110156124255761241a5f826123ef565b600181019050612408565b5050565b601f82111561246a5761243b8161231e565b61244484612330565b81016020851015612453578190505b61246761245f85612330565b830182612407565b50505b505050565b5f82821c905092915050565b5f61248a5f198460080261246f565b1980831691505092915050565b5f6124a2838361247b565b9150826002028217905092915050565b6124bb82612009565b67ffffffffffffffff8111156124d4576124d3611ae8565b5b6124de82546122ee565b6124e9828285612429565b5f60209050601f83116001811461251a575f8415612508578287015190505b6125128582612497565b865550612579565b601f1984166125288661231e565b5f5b8281101561254f5784890151825560018201915060208501945060208101905061252a565b8683101561256c5784890151612568601f89168261247b565b8355505b6001600288020188555050505b505050505050565b5f6020820190508181035f8301526125998184612031565b905092915050565b5f815190506125af81611df2565b92915050565b5f602082840312156125ca576125c9611a15565b5b5f6125d7848285016125a1565b91505092915050565b7f6f726967696e20746f6b656e20646f65736e27742065786973740000000000005f82015250565b5f612614601a83612013565b915061261f826125e0565b602082019050919050565b5f6020820190508181035f83015261264181612608565b9050919050565b5f81905092915050565b5f61265c82612009565b6126668185612648565b9350612676818560208601612023565b80840191505092915050565b5f61268d8285612652565b91506126998284612652565b91508190509392505050565b5f6126af82611c0c565b91506126ba83611c0c565b9250828203905060ff8111156126d3576126d26121a4565b5b92915050565b5f8160011c9050919050565b5f808291508390505b600185111561272e5780860481111561270a576127096121a4565b5b60018516156127195780820291505b8081029050612727856126d9565b94506126ee565b94509492505050565b5f826127465760019050612801565b81612753575f9050612801565b81600181146127695760028114612773576127a2565b6001915050612801565b60ff841115612785576127846121a4565b5b8360020a91508482111561279c5761279b6121a4565b5b50612801565b5060208310610133831016604e8410600b84101617156127d75782820a9050838111156127d2576127d16121a4565b5b612801565b6127e484848460016126e5565b925090508184048111156127fb576127fa6121a4565b5b81810290505b9392505050565b5f61281282611e1c565b915061281d83611e1c565b925061284a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8484612737565b905092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f61288982611e1c565b915061289483611e1c565b9250826128a4576128a3612852565b5b828204905092915050565b5f6128b982611e1c565b91506128c483611e1c565b92508282026128d281611e1c565b915082820484148315176128e9576128e86121a4565b5b5092915050565b7f636f6e76657274656420616d6f756e74206973207a65726f00000000000000005f82015250565b5f612924601883612013565b915061292f826128f0565b602082019050919050565b5f6020820190508181035f83015261295181612918565b9050919050565b7f7b224074797065223a20222f6962632e6170706c69636174696f6e732e7472615f8201527f6e736665722e76312e4d73675472616e73666572222c00000000000000000000602082015250565b5f6129b2603683612648565b91506129bd82612958565b603682019050919050565b7f22736f757263655f706f7274223a20227472616e73666572222c0000000000005f82015250565b5f6129fc601a83612648565b9150612a07826129c8565b601a82019050919050565b7f22736f757263655f6368616e6e656c223a2022000000000000000000000000005f82015250565b5f612a46601383612648565b9150612a5182612a12565b601382019050919050565b7f222c0000000000000000000000000000000000000000000000000000000000005f82015250565b5f612a90600283612648565b9150612a9b82612a5c565b600282019050919050565b7f22746f6b656e223a207b202264656e6f6d223a202200000000000000000000005f82015250565b5f612ada601583612648565b9150612ae582612aa6565b601582019050919050565b7f22616d6f756e74223a20220000000000000000000000000000000000000000005f82015250565b5f612b24600b83612648565b9150612b2f82612af0565b600b82019050919050565b7f227d2c00000000000000000000000000000000000000000000000000000000005f82015250565b5f612b6e600383612648565b9150612b7982612b3a565b600382019050919050565b7f2273656e646572223a20220000000000000000000000000000000000000000005f82015250565b5f612bb8600b83612648565b9150612bc382612b84565b600b82019050919050565b7f227265636569766572223a2022000000000000000000000000000000000000005f82015250565b5f612c02600d83612648565b9150612c0d82612bce565b600d82019050919050565b7f2274696d656f75745f686569676874223a207b227265766973696f6e5f6e756d5f8201527f626572223a202230222c227265766973696f6e5f686569676874223a2022302260208201527f7d2c000000000000000000000000000000000000000000000000000000000000604082015250565b5f612c98604283612648565b9150612ca382612c18565b604282019050919050565b7f2274696d656f75745f74696d657374616d70223a2022000000000000000000005f82015250565b5f612ce2601683612648565b9150612ced82612cae565b601682019050919050565b7f226d656d6f223a2022222c0000000000000000000000000000000000000000005f82015250565b5f612d2c600b83612648565b9150612d3782612cf8565b600b82019050919050565b7f226173796e635f63616c6c6261636b223a207b226964223a20220000000000005f82015250565b5f612d76601a83612648565b9150612d8182612d42565b601a82019050919050565b7f22636f6e74726163745f61646472657373223a202200000000000000000000005f82015250565b5f612dc0601583612648565b9150612dcb82612d8c565b601582019050919050565b7f227d7d00000000000000000000000000000000000000000000000000000000005f82015250565b5f612e0a600383612648565b9150612e1582612dd6565b600382019050919050565b5f612e2a826129a6565b9150612e35826129f0565b9150612e4082612a3a565b9150612e4c828b612652565b9150612e5782612a84565b9150612e6282612ace565b9150612e6e828a612652565b9150612e7982612a84565b9150612e8482612b18565b9150612e908289612652565b9150612e9b82612b62565b9150612ea682612bac565b9150612eb28288612652565b9150612ebd82612a84565b9150612ec882612bf6565b9150612ed48287612652565b9150612edf82612a84565b9150612eea82612c8c565b9150612ef582612cd6565b9150612f018286612652565b9150612f0c82612a84565b9150612f1782612d20565b9150612f2282612d6a565b9150612f2e8285612652565b9150612f3982612a84565b9150612f4482612db4565b9150612f508284612652565b9150612f5b82612dfe565b91508190509998505050505050505050565b5f612f7782611e1c565b9150612f8283611e1c565b9250828201905080821115612f9a57612f996121a4565b5b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f612fd782611e1c565b91505f8203612fe957612fe86121a4565b5b600182039050919050565b5f6040820190506130075f8301856120fa565b61301460208301846120fa565b939250505056fe608060405234801561000f575f80fd5b5060405161204338038061204383398181016040528101906100319190610235565b335f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550826003908161007f91906104ca565b50816004908161008f91906104ca565b508060055f6101000a81548160ff021916908360ff160217905550505050610599565b5f604051905090565b5f80fd5b5f80fd5b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b610111826100cb565b810181811067ffffffffffffffff821117156101305761012f6100db565b5b80604052505050565b5f6101426100b2565b905061014e8282610108565b919050565b5f67ffffffffffffffff82111561016d5761016c6100db565b5b610176826100cb565b9050602081019050919050565b8281835e5f83830152505050565b5f6101a361019e84610153565b610139565b9050828152602081018484840111156101bf576101be6100c7565b5b6101ca848285610183565b509392505050565b5f82601f8301126101e6576101e56100c3565b5b81516101f6848260208601610191565b91505092915050565b5f60ff82169050919050565b610214816101ff565b811461021e575f80fd5b50565b5f8151905061022f8161020b565b92915050565b5f805f6060848603121561024c5761024b6100bb565b5b5f84015167ffffffffffffffff811115610269576102686100bf565b5b610275868287016101d2565b935050602084015167ffffffffffffffff811115610296576102956100bf565b5b6102a2868287016101d2565b92505060406102b386828701610221565b9150509250925092565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061030b57607f821691505b60208210810361031e5761031d6102c7565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026103807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82610345565b61038a8683610345565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f6103ce6103c96103c4846103a2565b6103ab565b6103a2565b9050919050565b5f819050919050565b6103e7836103b4565b6103fb6103f3826103d5565b848454610351565b825550505050565b5f90565b61040f610403565b61041a8184846103de565b505050565b5b8181101561043d576104325f82610407565b600181019050610420565b5050565b601f8211156104825761045381610324565b61045c84610336565b8101602085101561046b578190505b61047f61047785610336565b83018261041f565b50505b505050565b5f82821c905092915050565b5f6104a25f1984600802610487565b1980831691505092915050565b5f6104ba8383610493565b9150826002028217905092915050565b6104d3826102bd565b67ffffffffffffffff8111156104ec576104eb6100db565b5b6104f682546102f4565b610501828285610441565b5f60209050601f831160018114610532575f8415610520578287015190505b61052a85826104af565b865550610591565b601f19841661054086610324565b5f5b8281101561056757848901518255600182019150602085019450602081019050610542565b868310156105845784890151610580601f891682610493565b8355505b6001600288020188555050505b505050505050565b611a9d806105a65f395ff3fe608060405234801561000f575f80fd5b5060043610610114575f3560e01c806342966c68116100a057806395d89b411161006f57806395d89b41146102f0578063a9059cbb1461030e578063dd62ed3e1461033e578063f2fde38b1461036e578063fe1195ec1461038a57610114565b806342966c681461025657806370a082311461027257806379cc6790146102a25780638da5cb5b146102d257610114565b80631988513b116100e75780631988513b146101b457806323b872dd146101d05780632d688ca814610200578063313ce5671461021c57806340c10f191461023a57610114565b806301ffc9a71461011857806306fdde0314610148578063095ea7b31461016657806318160ddd14610196575b5f80fd5b610132600480360381019061012d919061143b565b6103a6565b60405161013f9190611480565b60405180910390f35b61015061041f565b60405161015d9190611509565b60405180910390f35b610180600480360381019061017b91906115b6565b6104ab565b60405161018d9190611480565b60405180910390f35b61019e610598565b6040516101ab9190611603565b60405180910390f35b6101ce60048036038101906101c9919061161c565b61059e565b005b6101ea60048036038101906101e5919061161c565b61061d565b6040516101f79190611480565b60405180910390f35b61021a600480360381019061021591906115b6565b61077d565b005b6102246107fa565b6040516102319190611687565b60405180910390f35b610254600480360381019061024f91906115b6565b61080c565b005b610270600480360381019061026b91906116a0565b61092b565b005b61028c600480360381019061028791906116cb565b6109f3565b6040516102999190611603565b60405180910390f35b6102bc60048036038101906102b791906115b6565b610a08565b6040516102c99190611480565b60405180910390f35b6102da610b66565b6040516102e79190611705565b60405180910390f35b6102f8610b89565b6040516103059190611509565b60405180910390f35b610328600480360381019061032391906115b6565b610c15565b6040516103359190611480565b60405180910390f35b6103586004803603810190610353919061171e565b610ce6565b6040516103659190611603565b60405180910390f35b610388600480360381019061038391906116cb565b610d06565b005b6103a4600480360381019061039f91906115b6565b610e4e565b005b5f7f8da6da19000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610418575061041782610ecb565b5b9050919050565b6003805461042c90611789565b80601f016020809104026020016040519081016040528092919081815260200182805461045890611789565b80156104a35780601f1061047a576101008083540402835291602001916104a3565b820191905f5260205f20905b81548152906001019060200180831161048657829003601f168201915b505050505081565b5f8160025f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040516105869190611603565b60405180910390a36001905092915050565b60065481565b600173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461060d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161060490611803565b60405180910390fd5b610618838383610f34565b505050565b5f8260f173ffffffffffffffffffffffffffffffffffffffff1663f2af9ac9826040518263ffffffff1660e01b81526004016106599190611705565b602060405180830381865afa158015610674573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610698919061184b565b156106d8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106cf906118e6565b60405180910390fd5b8260025f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461075f9190611931565b92505081905550610771858585610f34565b60019150509392505050565b600173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146107ec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107e390611803565b60405180910390fd5b6107f6828261113f565b5050565b60055f9054906101000a900460ff1681565b8160f173ffffffffffffffffffffffffffffffffffffffff1663f2af9ac9826040518263ffffffff1660e01b81526004016108479190611705565b602060405180830381865afa158015610862573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610886919061184b565b156108c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108bd906119ae565b60405180910390fd5b5f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461091c575f80fd5b610926838361113f565b505050565b3360f173ffffffffffffffffffffffffffffffffffffffff166360dc402f826040518263ffffffff1660e01b81526004016109669190611705565b602060405180830381865afa158015610981573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109a5919061184b565b156109e5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109dc90611a16565b60405180910390fd5b6109ef338361130e565b5050565b6001602052805f5260405f205f915090505481565b5f8260f173ffffffffffffffffffffffffffffffffffffffff166360dc402f826040518263ffffffff1660e01b8152600401610a449190611705565b602060405180830381865afa158015610a5f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a83919061184b565b15610ac3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aba90611a16565b60405180910390fd5b8260025f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254610b4a9190611931565b92505081905550610b5b848461130e565b600191505092915050565b5f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60048054610b9690611789565b80601f0160208091040260200160405190810160405280929190818152602001828054610bc290611789565b8015610c0d5780601f10610be457610100808354040283529160200191610c0d565b820191905f5260205f20905b815481529060010190602001808311610bf057829003601f168201915b505050505081565b5f8260f173ffffffffffffffffffffffffffffffffffffffff1663f2af9ac9826040518263ffffffff1660e01b8152600401610c519190611705565b602060405180830381865afa158015610c6c573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c90919061184b565b15610cd0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cc7906118e6565b60405180910390fd5b610cdb338585610f34565b600191505092915050565b6002602052815f5260405f20602052805f5260405f205f91509150505481565b5f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610d5c575f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610d93575f80fd5b8073ffffffffffffffffffffffffffffffffffffffff165f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3805f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610ebd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610eb490611803565b60405180910390fd5b610ec7828261130e565b5050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b8160f273ffffffffffffffffffffffffffffffffffffffff16634e25ab64826040518263ffffffff1660e01b8152600401610f6f9190611705565b602060405180830381865afa158015610f8a573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610fae919061184b565b61102e5760f273ffffffffffffffffffffffffffffffffffffffff1663ceeae52a826040518263ffffffff1660e01b8152600401610fec9190611705565b6020604051808303815f875af1158015611008573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061102c919061184b565b505b8160015f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461107a9190611931565b925050819055508160015f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546110cd9190611a34565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516111319190611603565b60405180910390a350505050565b8160f273ffffffffffffffffffffffffffffffffffffffff16634e25ab64826040518263ffffffff1660e01b815260040161117a9190611705565b602060405180830381865afa158015611195573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111b9919061184b565b6112395760f273ffffffffffffffffffffffffffffffffffffffff1663ceeae52a826040518263ffffffff1660e01b81526004016111f79190611705565b6020604051808303815f875af1158015611213573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611237919061184b565b505b8160015f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546112859190611a34565b925050819055508160065f82825461129d9190611a34565b925050819055508273ffffffffffffffffffffffffffffffffffffffff165f73ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516113019190611603565b60405180910390a3505050565b8060015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461135a9190611931565b925050819055508060065f8282546113729190611931565b925050819055505f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516113d69190611603565b60405180910390a35050565b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61141a816113e6565b8114611424575f80fd5b50565b5f8135905061143581611411565b92915050565b5f602082840312156114505761144f6113e2565b5b5f61145d84828501611427565b91505092915050565b5f8115159050919050565b61147a81611466565b82525050565b5f6020820190506114935f830184611471565b92915050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f6114db82611499565b6114e581856114a3565b93506114f58185602086016114b3565b6114fe816114c1565b840191505092915050565b5f6020820190508181035f83015261152181846114d1565b905092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61155282611529565b9050919050565b61156281611548565b811461156c575f80fd5b50565b5f8135905061157d81611559565b92915050565b5f819050919050565b61159581611583565b811461159f575f80fd5b50565b5f813590506115b08161158c565b92915050565b5f80604083850312156115cc576115cb6113e2565b5b5f6115d98582860161156f565b92505060206115ea858286016115a2565b9150509250929050565b6115fd81611583565b82525050565b5f6020820190506116165f8301846115f4565b92915050565b5f805f60608486031215611633576116326113e2565b5b5f6116408682870161156f565b93505060206116518682870161156f565b9250506040611662868287016115a2565b9150509250925092565b5f60ff82169050919050565b6116818161166c565b82525050565b5f60208201905061169a5f830184611678565b92915050565b5f602082840312156116b5576116b46113e2565b5b5f6116c2848285016115a2565b91505092915050565b5f602082840312156116e0576116df6113e2565b5b5f6116ed8482850161156f565b91505092915050565b6116ff81611548565b82525050565b5f6020820190506117185f8301846116f6565b92915050565b5f8060408385031215611734576117336113e2565b5b5f6117418582860161156f565b92505060206117528582860161156f565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806117a057607f821691505b6020821081036117b3576117b261175c565b5b50919050565b7f45524332303a2063616c6c6572206973206e6f742074686520636861696e00005f82015250565b5f6117ed601e836114a3565b91506117f8826117b9565b602082019050919050565b5f6020820190508181035f83015261181a816117e1565b9050919050565b61182a81611466565b8114611834575f80fd5b50565b5f8151905061184581611821565b92915050565b5f602082840312156118605761185f6113e2565b5b5f61186d84828501611837565b91505092915050565b7f45524332303a207472616e7366657220746f20626c6f636b65642061646472655f8201527f7373000000000000000000000000000000000000000000000000000000000000602082015250565b5f6118d06022836114a3565b91506118db82611876565b604082019050919050565b5f6020820190508181035f8301526118fd816118c4565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61193b82611583565b915061194683611583565b925082820390508181111561195e5761195d611904565b5b92915050565b7f45524332303a206d696e7420746f20626c6f636b6564206164647265737300005f82015250565b5f611998601e836114a3565b91506119a382611964565b602082019050919050565b5f6020820190508181035f8301526119c58161198c565b9050919050565b7f45524332303a206275726e2066726f6d206d6f64756c652061646472657373005f82015250565b5f611a00601f836114a3565b9150611a0b826119cc565b602082019050919050565b5f6020820190508181035f830152611a2d816119f4565b9050919050565b5f611a3e82611583565b9150611a4983611583565b9250828201905080821115611a6157611a60611904565b5b9291505056fea2646970667358221220de4043b1adb87162ffc06c0127fc335d705e04b467c9acd7522c8721ebd4c4bb64736f6c63430008190033a264697066735822122033c4a84f26f98b6e3f572377d6071b375cf3c1833cddb53e89437ad4f0d8196a64736f6c63430008190033", + Bin: "0x60a06040525f8060146101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550348015610037575f80fd5b5060405161520e38038061520e83398181016040528101906100599190610130565b335f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff16815250505061015b565b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6100ff826100d6565b9050919050565b61010f816100f5565b8114610119575f80fd5b50565b5f8151905061012a81610106565b92915050565b5f60208284031215610145576101446100d2565b5b5f6101528482850161011c565b91505092915050565b60805161509461017a5f395f8181610935015261101501526150945ff3fe608060405234801561000f575f80fd5b50600436106100a7575f3560e01c80639a1114321161006f5780639a11143214610161578063b5ad1fb61461017d578063c45a0155146101ad578063d5c6b504146101cb578063f2fde38b146101fb578063fc07875814610217576100a7565b806301ffc9a7146100ab57806306ef1a86146100db5780630d4f1f9d1461010b57806331a503f0146101275780638da5cb5b14610143575b5f80fd5b6100c560048036038101906100c09190611a72565b610233565b6040516100d29190611ab7565b60405180910390f35b6100f560048036038101906100f09190611c42565b61029c565b6040516101029190611d09565b60405180910390f35b61012560048036038101906101209190611d89565b61041b565b005b610141600480360381019061013c9190611dc7565b61042e565b005b61014b61043a565b6040516101589190611d09565b60405180910390f35b61017b60048036038101906101769190611e4f565b61045d565b005b61019760048036038101906101929190611efe565b610903565b6040516101a49190611d09565b60405180910390f35b6101b5610933565b6040516101c29190611f84565b60405180910390f35b6101e560048036038101906101e09190611efe565b610957565b6040516101f29190611d09565b60405180910390f35b61021560048036038101906102109190611efe565b610987565b005b610231600480360381019061022c9190611f9d565b610acf565b005b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b5f808484846040516102ad906119ff565b6102b993929190612078565b604051809103905ff0801580156102d2573d5f803e3d5ffd5b50905060f273ffffffffffffffffffffffffffffffffffffffff1663d126274a826040518263ffffffff1660e01b815260040161030f9190611d09565b6020604051808303815f875af115801561032b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061034f91906120cf565b508073ffffffffffffffffffffffffffffffffffffffff1663f2fde38b336040518263ffffffff1660e01b81526004016103899190611d09565b5f604051808303815f87803b1580156103a0575f80fd5b505af11580156103b2573d5f803e3d5ffd5b505050503373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f85e892981b234101136bc30081e0a5c44345bebc0940193230c20a43b279e2d160405160405180910390a3809150509392505050565b8061042a5761042982610e48565b5b5050565b61043781610e48565b50565b5f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b61046684610f83565b8373ffffffffffffffffffffffffffffffffffffffff166323b872dd3330856040518463ffffffff1660e01b81526004016104a393929190612109565b6020604051808303815f875af11580156104bf573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104e391906120cf565b505f61055d838673ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610532573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105569190612152565b6006611338565b905060015f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166340c10f1930836040518363ffffffff1660e01b81526004016105f692919061217d565b5f604051808303815f87803b15801561060d575f80fd5b505af115801561061f573d5f803e3d5ffd5b5050505060015f60148282829054906101000a900467ffffffffffffffff1661064891906121d1565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060405180606001604052803373ffffffffffffffffffffffffffffffffffffffff16815260200160f173ffffffffffffffffffffffffffffffffffffffff166381cf0f6a60015f8a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518263ffffffff1660e01b815260040161072b9190611d09565b5f604051808303815f875af1158015610746573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f8201168201806040525081019061076e919061227a565b81526020018281525060035f8060149054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff1681526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550602082015181600101908161080a91906124b2565b506040820151816002015590505060f173ffffffffffffffffffffffffffffffffffffffff1663d46f64e661089e8860015f8a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1685878a611407565b6040518263ffffffff1660e01b81526004016108ba9190612581565b6020604051808303815f875af11580156108d6573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108fa91906120cf565b50505050505050565b6002602052805f5260405f205f915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b7f000000000000000000000000000000000000000000000000000000000000000081565b6001602052805f5260405f205f915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146109dd575f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610a14575f80fd5b8073ffffffffffffffffffffffffffffffffffffffff165f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3805f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b5f60f173ffffffffffffffffffffffffffffffffffffffff16632b3324ce856040518263ffffffff1660e01b8152600401610b0a9190612581565b6020604051808303815f875af1158015610b26573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b4a91906125b5565b90505f73ffffffffffffffffffffffffffffffffffffffff1660025f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1603610c16576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c0d9061262a565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166379cc679033846040518363ffffffff1660e01b8152600401610c5192919061217d565b6020604051808303815f875af1158015610c6d573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c9191906120cf565b505f610d6783600660025f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d3e573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d629190612152565b611338565b905060025f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb85836040518363ffffffff1660e01b8152600401610e0092919061217d565b6020604051808303815f875af1158015610e1c573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e4091906120cf565b505050505050565b5f60035f8367ffffffffffffffff1667ffffffffffffffff1681526020019081526020015f206040518060600160405290815f82015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600182018054610edd906122ee565b80601f0160208091040260200160405190810160405280929190818152602001828054610f09906122ee565b8015610f545780601f10610f2b57610100808354040283529160200191610f54565b820191905f5260205f20905b815481529060010190602001808311610f3757829003601f168201915b505050505081526020016002820154815250509050610f7f8160200151825f01518360400151610acf565b5050565b5f73ffffffffffffffffffffffffffffffffffffffff1660015f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1603611335575f7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166306ef1a866040518060400160405280600781526020017f57726170706564000000000000000000000000000000000000000000000000008152508473ffffffffffffffffffffffffffffffffffffffff166306fdde036040518163ffffffff1660e01b81526004015f60405180830381865afa1580156110cd573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f820116820180604052508101906110f5919061227a565b604051602001611106929190612682565b6040516020818303038152906040526040518060400160405280600181526020017f57000000000000000000000000000000000000000000000000000000000000008152508573ffffffffffffffffffffffffffffffffffffffff166395d89b416040518163ffffffff1660e01b81526004015f60405180830381865afa158015611193573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f820116820180604052508101906111bb919061227a565b6040516020016111cc929190612682565b60405160208183030381529060405260066040518463ffffffff1660e01b81526004016111fb93929190612078565b6020604051808303815f875af1158015611217573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061123b91906125b5565b90508060015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508160025f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505b50565b5f8160ff168360ff161115611379575f828461135491906126a5565b60ff16600a6113639190612808565b90508085611371919061287f565b9150506113be565b8160ff168360ff1610156113b9575f838361139491906126a5565b60ff16600a6113a39190612808565b905080856113b191906128af565b9150506113bd565b8390505b5b5f8103611400576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113f79061293a565b60405180910390fd5b9392505050565b60608560f173ffffffffffffffffffffffffffffffffffffffff166381cf0f6a876040518263ffffffff1660e01b81526004016114449190611d09565b5f604051808303815f875af115801561145f573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f82011682018060405250810190611487919061227a565b61149086611579565b60f173ffffffffffffffffffffffffffffffffffffffff16636af32a55306040518263ffffffff1660e01b81526004016114ca9190611d09565b5f604051808303815f875af11580156114e5573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f8201168201806040525081019061150d919061227a565b8561151788611579565b61153f5f60149054906101000a900467ffffffffffffffff1667ffffffffffffffff16611579565b61154830611643565b60405160200161155f989796959493929190612e20565b604051602081830303815290604052905095945050505050565b60605f600161158784611670565b0190505f8167ffffffffffffffff8111156115a5576115a4611ae8565b5b6040519080825280601f01601f1916602001820160405280156115d75781602001600182028036833780820191505090505b5090505f82602001820190505b600115611638578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a858161162d5761162c612852565b5b0494505f85036115e4575b819350505050919050565b60606116698273ffffffffffffffffffffffffffffffffffffffff16601460ff166117c1565b9050919050565b5f805f90507a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083106116cc577a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083816116c2576116c1612852565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310611709576d04ee2d6d415b85acef810000000083816116ff576116fe612852565b5b0492506020810190505b662386f26fc10000831061173857662386f26fc10000838161172e5761172d612852565b5b0492506010810190505b6305f5e1008310611761576305f5e100838161175757611756612852565b5b0492506008810190505b612710831061178657612710838161177c5761177b612852565b5b0492506004810190505b606483106117a9576064838161179f5761179e612852565b5b0492506002810190505b600a83106117b8576001810190505b80915050919050565b60605f8390505f60028460026117d791906128af565b6117e19190612f6d565b67ffffffffffffffff8111156117fa576117f9611ae8565b5b6040519080825280601f01601f19166020018201604052801561182c5781602001600182028036833780820191505090505b5090507f3000000000000000000000000000000000000000000000000000000000000000815f8151811061186357611862612fa0565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053507f7800000000000000000000000000000000000000000000000000000000000000816001815181106118c6576118c5612fa0565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053505f600185600261190491906128af565b61190e9190612f6d565b90505b60018111156119ad577f3031323334353637383961626364656600000000000000000000000000000000600f8416601081106119505761194f612fa0565b5b1a60f81b82828151811061196757611966612fa0565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a905350600483901c9250806119a690612fcd565b9050611911565b505f82146119f45784846040517fe22e27eb0000000000000000000000000000000000000000000000000000000081526004016119eb929190612ff4565b60405180910390fd5b809250505092915050565b6120438061301c83390190565b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b611a5181611a1d565b8114611a5b575f80fd5b50565b5f81359050611a6c81611a48565b92915050565b5f60208284031215611a8757611a86611a15565b5b5f611a9484828501611a5e565b91505092915050565b5f8115159050919050565b611ab181611a9d565b82525050565b5f602082019050611aca5f830184611aa8565b92915050565b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b611b1e82611ad8565b810181811067ffffffffffffffff82111715611b3d57611b3c611ae8565b5b80604052505050565b5f611b4f611a0c565b9050611b5b8282611b15565b919050565b5f67ffffffffffffffff821115611b7a57611b79611ae8565b5b611b8382611ad8565b9050602081019050919050565b828183375f83830152505050565b5f611bb0611bab84611b60565b611b46565b905082815260208101848484011115611bcc57611bcb611ad4565b5b611bd7848285611b90565b509392505050565b5f82601f830112611bf357611bf2611ad0565b5b8135611c03848260208601611b9e565b91505092915050565b5f60ff82169050919050565b611c2181611c0c565b8114611c2b575f80fd5b50565b5f81359050611c3c81611c18565b92915050565b5f805f60608486031215611c5957611c58611a15565b5b5f84013567ffffffffffffffff811115611c7657611c75611a19565b5b611c8286828701611bdf565b935050602084013567ffffffffffffffff811115611ca357611ca2611a19565b5b611caf86828701611bdf565b9250506040611cc086828701611c2e565b9150509250925092565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f611cf382611cca565b9050919050565b611d0381611ce9565b82525050565b5f602082019050611d1c5f830184611cfa565b92915050565b5f67ffffffffffffffff82169050919050565b611d3e81611d22565b8114611d48575f80fd5b50565b5f81359050611d5981611d35565b92915050565b611d6881611a9d565b8114611d72575f80fd5b50565b5f81359050611d8381611d5f565b92915050565b5f8060408385031215611d9f57611d9e611a15565b5b5f611dac85828601611d4b565b9250506020611dbd85828601611d75565b9150509250929050565b5f60208284031215611ddc57611ddb611a15565b5b5f611de984828501611d4b565b91505092915050565b611dfb81611ce9565b8114611e05575f80fd5b50565b5f81359050611e1681611df2565b92915050565b5f819050919050565b611e2e81611e1c565b8114611e38575f80fd5b50565b5f81359050611e4981611e25565b92915050565b5f805f805f60a08688031215611e6857611e67611a15565b5b5f86013567ffffffffffffffff811115611e8557611e84611a19565b5b611e9188828901611bdf565b9550506020611ea288828901611e08565b945050604086013567ffffffffffffffff811115611ec357611ec2611a19565b5b611ecf88828901611bdf565b9350506060611ee088828901611e3b565b9250506080611ef188828901611e3b565b9150509295509295909350565b5f60208284031215611f1357611f12611a15565b5b5f611f2084828501611e08565b91505092915050565b5f819050919050565b5f611f4c611f47611f4284611cca565b611f29565b611cca565b9050919050565b5f611f5d82611f32565b9050919050565b5f611f6e82611f53565b9050919050565b611f7e81611f64565b82525050565b5f602082019050611f975f830184611f75565b92915050565b5f805f60608486031215611fb457611fb3611a15565b5b5f84013567ffffffffffffffff811115611fd157611fd0611a19565b5b611fdd86828701611bdf565b9350506020611fee86828701611e08565b9250506040611fff86828701611e3b565b9150509250925092565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f61203b82612009565b6120458185612013565b9350612055818560208601612023565b61205e81611ad8565b840191505092915050565b61207281611c0c565b82525050565b5f6060820190508181035f8301526120908186612031565b905081810360208301526120a48185612031565b90506120b36040830184612069565b949350505050565b5f815190506120c981611d5f565b92915050565b5f602082840312156120e4576120e3611a15565b5b5f6120f1848285016120bb565b91505092915050565b61210381611e1c565b82525050565b5f60608201905061211c5f830186611cfa565b6121296020830185611cfa565b61213660408301846120fa565b949350505050565b5f8151905061214c81611c18565b92915050565b5f6020828403121561216757612166611a15565b5b5f6121748482850161213e565b91505092915050565b5f6040820190506121905f830185611cfa565b61219d60208301846120fa565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f6121db82611d22565b91506121e683611d22565b9250828201905067ffffffffffffffff811115612206576122056121a4565b5b92915050565b5f61221e61221984611b60565b611b46565b90508281526020810184848401111561223a57612239611ad4565b5b612245848285612023565b509392505050565b5f82601f83011261226157612260611ad0565b5b815161227184826020860161220c565b91505092915050565b5f6020828403121561228f5761228e611a15565b5b5f82015167ffffffffffffffff8111156122ac576122ab611a19565b5b6122b88482850161224d565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061230557607f821691505b602082108103612318576123176122c1565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f6008830261237a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8261233f565b612384868361233f565b95508019841693508086168417925050509392505050565b5f6123b66123b16123ac84611e1c565b611f29565b611e1c565b9050919050565b5f819050919050565b6123cf8361239c565b6123e36123db826123bd565b84845461234b565b825550505050565b5f90565b6123f76123eb565b6124028184846123c6565b505050565b5b818110156124255761241a5f826123ef565b600181019050612408565b5050565b601f82111561246a5761243b8161231e565b61244484612330565b81016020851015612453578190505b61246761245f85612330565b830182612407565b50505b505050565b5f82821c905092915050565b5f61248a5f198460080261246f565b1980831691505092915050565b5f6124a2838361247b565b9150826002028217905092915050565b6124bb82612009565b67ffffffffffffffff8111156124d4576124d3611ae8565b5b6124de82546122ee565b6124e9828285612429565b5f60209050601f83116001811461251a575f8415612508578287015190505b6125128582612497565b865550612579565b601f1984166125288661231e565b5f5b8281101561254f5784890151825560018201915060208501945060208101905061252a565b8683101561256c5784890151612568601f89168261247b565b8355505b6001600288020188555050505b505050505050565b5f6020820190508181035f8301526125998184612031565b905092915050565b5f815190506125af81611df2565b92915050565b5f602082840312156125ca576125c9611a15565b5b5f6125d7848285016125a1565b91505092915050565b7f6f726967696e20746f6b656e20646f65736e27742065786973740000000000005f82015250565b5f612614601a83612013565b915061261f826125e0565b602082019050919050565b5f6020820190508181035f83015261264181612608565b9050919050565b5f81905092915050565b5f61265c82612009565b6126668185612648565b9350612676818560208601612023565b80840191505092915050565b5f61268d8285612652565b91506126998284612652565b91508190509392505050565b5f6126af82611c0c565b91506126ba83611c0c565b9250828203905060ff8111156126d3576126d26121a4565b5b92915050565b5f8160011c9050919050565b5f808291508390505b600185111561272e5780860481111561270a576127096121a4565b5b60018516156127195780820291505b8081029050612727856126d9565b94506126ee565b94509492505050565b5f826127465760019050612801565b81612753575f9050612801565b81600181146127695760028114612773576127a2565b6001915050612801565b60ff841115612785576127846121a4565b5b8360020a91508482111561279c5761279b6121a4565b5b50612801565b5060208310610133831016604e8410600b84101617156127d75782820a9050838111156127d2576127d16121a4565b5b612801565b6127e484848460016126e5565b925090508184048111156127fb576127fa6121a4565b5b81810290505b9392505050565b5f61281282611e1c565b915061281d83611e1c565b925061284a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8484612737565b905092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f61288982611e1c565b915061289483611e1c565b9250826128a4576128a3612852565b5b828204905092915050565b5f6128b982611e1c565b91506128c483611e1c565b92508282026128d281611e1c565b915082820484148315176128e9576128e86121a4565b5b5092915050565b7f636f6e76657274656420616d6f756e74206973207a65726f00000000000000005f82015250565b5f612924601883612013565b915061292f826128f0565b602082019050919050565b5f6020820190508181035f83015261295181612918565b9050919050565b7f7b224074797065223a20222f6962632e6170706c69636174696f6e732e7472615f8201527f6e736665722e76312e4d73675472616e73666572222c00000000000000000000602082015250565b5f6129b2603683612648565b91506129bd82612958565b603682019050919050565b7f22736f757263655f706f7274223a20227472616e73666572222c0000000000005f82015250565b5f6129fc601a83612648565b9150612a07826129c8565b601a82019050919050565b7f22736f757263655f6368616e6e656c223a2022000000000000000000000000005f82015250565b5f612a46601383612648565b9150612a5182612a12565b601382019050919050565b7f222c0000000000000000000000000000000000000000000000000000000000005f82015250565b5f612a90600283612648565b9150612a9b82612a5c565b600282019050919050565b7f22746f6b656e223a207b202264656e6f6d223a202200000000000000000000005f82015250565b5f612ada601583612648565b9150612ae582612aa6565b601582019050919050565b7f22616d6f756e74223a20220000000000000000000000000000000000000000005f82015250565b5f612b24600b83612648565b9150612b2f82612af0565b600b82019050919050565b7f227d2c00000000000000000000000000000000000000000000000000000000005f82015250565b5f612b6e600383612648565b9150612b7982612b3a565b600382019050919050565b7f2273656e646572223a20220000000000000000000000000000000000000000005f82015250565b5f612bb8600b83612648565b9150612bc382612b84565b600b82019050919050565b7f227265636569766572223a2022000000000000000000000000000000000000005f82015250565b5f612c02600d83612648565b9150612c0d82612bce565b600d82019050919050565b7f2274696d656f75745f686569676874223a207b227265766973696f6e5f6e756d5f8201527f626572223a202230222c227265766973696f6e5f686569676874223a2022302260208201527f7d2c000000000000000000000000000000000000000000000000000000000000604082015250565b5f612c98604283612648565b9150612ca382612c18565b604282019050919050565b7f2274696d656f75745f74696d657374616d70223a2022000000000000000000005f82015250565b5f612ce2601683612648565b9150612ced82612cae565b601682019050919050565b7f226d656d6f223a2022222c0000000000000000000000000000000000000000005f82015250565b5f612d2c600b83612648565b9150612d3782612cf8565b600b82019050919050565b7f226173796e635f63616c6c6261636b223a207b226964223a20220000000000005f82015250565b5f612d76601a83612648565b9150612d8182612d42565b601a82019050919050565b7f22636f6e74726163745f61646472657373223a202200000000000000000000005f82015250565b5f612dc0601583612648565b9150612dcb82612d8c565b601582019050919050565b7f227d7d00000000000000000000000000000000000000000000000000000000005f82015250565b5f612e0a600383612648565b9150612e1582612dd6565b600382019050919050565b5f612e2a826129a6565b9150612e35826129f0565b9150612e4082612a3a565b9150612e4c828b612652565b9150612e5782612a84565b9150612e6282612ace565b9150612e6e828a612652565b9150612e7982612a84565b9150612e8482612b18565b9150612e908289612652565b9150612e9b82612b62565b9150612ea682612bac565b9150612eb28288612652565b9150612ebd82612a84565b9150612ec882612bf6565b9150612ed48287612652565b9150612edf82612a84565b9150612eea82612c8c565b9150612ef582612cd6565b9150612f018286612652565b9150612f0c82612a84565b9150612f1782612d20565b9150612f2282612d6a565b9150612f2e8285612652565b9150612f3982612a84565b9150612f4482612db4565b9150612f508284612652565b9150612f5b82612dfe565b91508190509998505050505050505050565b5f612f7782611e1c565b9150612f8283611e1c565b9250828201905080821115612f9a57612f996121a4565b5b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f612fd782611e1c565b91505f8203612fe957612fe86121a4565b5b600182039050919050565b5f6040820190506130075f8301856120fa565b61301460208301846120fa565b939250505056fe608060405234801561000f575f80fd5b5060405161204338038061204383398181016040528101906100319190610235565b335f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550826003908161007f91906104ca565b50816004908161008f91906104ca565b508060055f6101000a81548160ff021916908360ff160217905550505050610599565b5f604051905090565b5f80fd5b5f80fd5b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b610111826100cb565b810181811067ffffffffffffffff821117156101305761012f6100db565b5b80604052505050565b5f6101426100b2565b905061014e8282610108565b919050565b5f67ffffffffffffffff82111561016d5761016c6100db565b5b610176826100cb565b9050602081019050919050565b8281835e5f83830152505050565b5f6101a361019e84610153565b610139565b9050828152602081018484840111156101bf576101be6100c7565b5b6101ca848285610183565b509392505050565b5f82601f8301126101e6576101e56100c3565b5b81516101f6848260208601610191565b91505092915050565b5f60ff82169050919050565b610214816101ff565b811461021e575f80fd5b50565b5f8151905061022f8161020b565b92915050565b5f805f6060848603121561024c5761024b6100bb565b5b5f84015167ffffffffffffffff811115610269576102686100bf565b5b610275868287016101d2565b935050602084015167ffffffffffffffff811115610296576102956100bf565b5b6102a2868287016101d2565b92505060406102b386828701610221565b9150509250925092565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061030b57607f821691505b60208210810361031e5761031d6102c7565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026103807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82610345565b61038a8683610345565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f6103ce6103c96103c4846103a2565b6103ab565b6103a2565b9050919050565b5f819050919050565b6103e7836103b4565b6103fb6103f3826103d5565b848454610351565b825550505050565b5f90565b61040f610403565b61041a8184846103de565b505050565b5b8181101561043d576104325f82610407565b600181019050610420565b5050565b601f8211156104825761045381610324565b61045c84610336565b8101602085101561046b578190505b61047f61047785610336565b83018261041f565b50505b505050565b5f82821c905092915050565b5f6104a25f1984600802610487565b1980831691505092915050565b5f6104ba8383610493565b9150826002028217905092915050565b6104d3826102bd565b67ffffffffffffffff8111156104ec576104eb6100db565b5b6104f682546102f4565b610501828285610441565b5f60209050601f831160018114610532575f8415610520578287015190505b61052a85826104af565b865550610591565b601f19841661054086610324565b5f5b8281101561056757848901518255600182019150602085019450602081019050610542565b868310156105845784890151610580601f891682610493565b8355505b6001600288020188555050505b505050505050565b611a9d806105a65f395ff3fe608060405234801561000f575f80fd5b5060043610610114575f3560e01c806342966c68116100a057806395d89b411161006f57806395d89b41146102f0578063a9059cbb1461030e578063dd62ed3e1461033e578063f2fde38b1461036e578063fe1195ec1461038a57610114565b806342966c681461025657806370a082311461027257806379cc6790146102a25780638da5cb5b146102d257610114565b80631988513b116100e75780631988513b146101b457806323b872dd146101d05780632d688ca814610200578063313ce5671461021c57806340c10f191461023a57610114565b806301ffc9a71461011857806306fdde0314610148578063095ea7b31461016657806318160ddd14610196575b5f80fd5b610132600480360381019061012d919061143b565b6103a6565b60405161013f9190611480565b60405180910390f35b61015061041f565b60405161015d9190611509565b60405180910390f35b610180600480360381019061017b91906115b6565b6104ab565b60405161018d9190611480565b60405180910390f35b61019e610598565b6040516101ab9190611603565b60405180910390f35b6101ce60048036038101906101c9919061161c565b61059e565b005b6101ea60048036038101906101e5919061161c565b61061d565b6040516101f79190611480565b60405180910390f35b61021a600480360381019061021591906115b6565b61077d565b005b6102246107fa565b6040516102319190611687565b60405180910390f35b610254600480360381019061024f91906115b6565b61080c565b005b610270600480360381019061026b91906116a0565b61092b565b005b61028c600480360381019061028791906116cb565b6109f3565b6040516102999190611603565b60405180910390f35b6102bc60048036038101906102b791906115b6565b610a08565b6040516102c99190611480565b60405180910390f35b6102da610b66565b6040516102e79190611705565b60405180910390f35b6102f8610b89565b6040516103059190611509565b60405180910390f35b610328600480360381019061032391906115b6565b610c15565b6040516103359190611480565b60405180910390f35b6103586004803603810190610353919061171e565b610ce6565b6040516103659190611603565b60405180910390f35b610388600480360381019061038391906116cb565b610d06565b005b6103a4600480360381019061039f91906115b6565b610e4e565b005b5f7f8da6da19000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610418575061041782610ecb565b5b9050919050565b6003805461042c90611789565b80601f016020809104026020016040519081016040528092919081815260200182805461045890611789565b80156104a35780601f1061047a576101008083540402835291602001916104a3565b820191905f5260205f20905b81548152906001019060200180831161048657829003601f168201915b505050505081565b5f8160025f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040516105869190611603565b60405180910390a36001905092915050565b60065481565b600173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461060d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161060490611803565b60405180910390fd5b610618838383610f34565b505050565b5f8260f173ffffffffffffffffffffffffffffffffffffffff1663f2af9ac9826040518263ffffffff1660e01b81526004016106599190611705565b602060405180830381865afa158015610674573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610698919061184b565b156106d8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106cf906118e6565b60405180910390fd5b8260025f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461075f9190611931565b92505081905550610771858585610f34565b60019150509392505050565b600173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146107ec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107e390611803565b60405180910390fd5b6107f6828261113f565b5050565b60055f9054906101000a900460ff1681565b8160f173ffffffffffffffffffffffffffffffffffffffff1663f2af9ac9826040518263ffffffff1660e01b81526004016108479190611705565b602060405180830381865afa158015610862573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610886919061184b565b156108c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108bd906119ae565b60405180910390fd5b5f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461091c575f80fd5b610926838361113f565b505050565b3360f173ffffffffffffffffffffffffffffffffffffffff166360dc402f826040518263ffffffff1660e01b81526004016109669190611705565b602060405180830381865afa158015610981573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109a5919061184b565b156109e5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109dc90611a16565b60405180910390fd5b6109ef338361130e565b5050565b6001602052805f5260405f205f915090505481565b5f8260f173ffffffffffffffffffffffffffffffffffffffff166360dc402f826040518263ffffffff1660e01b8152600401610a449190611705565b602060405180830381865afa158015610a5f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a83919061184b565b15610ac3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aba90611a16565b60405180910390fd5b8260025f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254610b4a9190611931565b92505081905550610b5b848461130e565b600191505092915050565b5f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60048054610b9690611789565b80601f0160208091040260200160405190810160405280929190818152602001828054610bc290611789565b8015610c0d5780601f10610be457610100808354040283529160200191610c0d565b820191905f5260205f20905b815481529060010190602001808311610bf057829003601f168201915b505050505081565b5f8260f173ffffffffffffffffffffffffffffffffffffffff1663f2af9ac9826040518263ffffffff1660e01b8152600401610c519190611705565b602060405180830381865afa158015610c6c573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c90919061184b565b15610cd0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cc7906118e6565b60405180910390fd5b610cdb338585610f34565b600191505092915050565b6002602052815f5260405f20602052805f5260405f205f91509150505481565b5f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610d5c575f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610d93575f80fd5b8073ffffffffffffffffffffffffffffffffffffffff165f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3805f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610ebd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610eb490611803565b60405180910390fd5b610ec7828261130e565b5050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b8160f273ffffffffffffffffffffffffffffffffffffffff16634e25ab64826040518263ffffffff1660e01b8152600401610f6f9190611705565b602060405180830381865afa158015610f8a573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610fae919061184b565b61102e5760f273ffffffffffffffffffffffffffffffffffffffff1663ceeae52a826040518263ffffffff1660e01b8152600401610fec9190611705565b6020604051808303815f875af1158015611008573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061102c919061184b565b505b8160015f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461107a9190611931565b925050819055508160015f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546110cd9190611a34565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516111319190611603565b60405180910390a350505050565b8160f273ffffffffffffffffffffffffffffffffffffffff16634e25ab64826040518263ffffffff1660e01b815260040161117a9190611705565b602060405180830381865afa158015611195573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111b9919061184b565b6112395760f273ffffffffffffffffffffffffffffffffffffffff1663ceeae52a826040518263ffffffff1660e01b81526004016111f79190611705565b6020604051808303815f875af1158015611213573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611237919061184b565b505b8160015f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546112859190611a34565b925050819055508160065f82825461129d9190611a34565b925050819055508273ffffffffffffffffffffffffffffffffffffffff165f73ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516113019190611603565b60405180910390a3505050565b8060015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825461135a9190611931565b925050819055508060065f8282546113729190611931565b925050819055505f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516113d69190611603565b60405180910390a35050565b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61141a816113e6565b8114611424575f80fd5b50565b5f8135905061143581611411565b92915050565b5f602082840312156114505761144f6113e2565b5b5f61145d84828501611427565b91505092915050565b5f8115159050919050565b61147a81611466565b82525050565b5f6020820190506114935f830184611471565b92915050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f6114db82611499565b6114e581856114a3565b93506114f58185602086016114b3565b6114fe816114c1565b840191505092915050565b5f6020820190508181035f83015261152181846114d1565b905092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61155282611529565b9050919050565b61156281611548565b811461156c575f80fd5b50565b5f8135905061157d81611559565b92915050565b5f819050919050565b61159581611583565b811461159f575f80fd5b50565b5f813590506115b08161158c565b92915050565b5f80604083850312156115cc576115cb6113e2565b5b5f6115d98582860161156f565b92505060206115ea858286016115a2565b9150509250929050565b6115fd81611583565b82525050565b5f6020820190506116165f8301846115f4565b92915050565b5f805f60608486031215611633576116326113e2565b5b5f6116408682870161156f565b93505060206116518682870161156f565b9250506040611662868287016115a2565b9150509250925092565b5f60ff82169050919050565b6116818161166c565b82525050565b5f60208201905061169a5f830184611678565b92915050565b5f602082840312156116b5576116b46113e2565b5b5f6116c2848285016115a2565b91505092915050565b5f602082840312156116e0576116df6113e2565b5b5f6116ed8482850161156f565b91505092915050565b6116ff81611548565b82525050565b5f6020820190506117185f8301846116f6565b92915050565b5f8060408385031215611734576117336113e2565b5b5f6117418582860161156f565b92505060206117528582860161156f565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806117a057607f821691505b6020821081036117b3576117b261175c565b5b50919050565b7f45524332303a2063616c6c6572206973206e6f742074686520636861696e00005f82015250565b5f6117ed601e836114a3565b91506117f8826117b9565b602082019050919050565b5f6020820190508181035f83015261181a816117e1565b9050919050565b61182a81611466565b8114611834575f80fd5b50565b5f8151905061184581611821565b92915050565b5f602082840312156118605761185f6113e2565b5b5f61186d84828501611837565b91505092915050565b7f45524332303a207472616e7366657220746f20626c6f636b65642061646472655f8201527f7373000000000000000000000000000000000000000000000000000000000000602082015250565b5f6118d06022836114a3565b91506118db82611876565b604082019050919050565b5f6020820190508181035f8301526118fd816118c4565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61193b82611583565b915061194683611583565b925082820390508181111561195e5761195d611904565b5b92915050565b7f45524332303a206d696e7420746f20626c6f636b6564206164647265737300005f82015250565b5f611998601e836114a3565b91506119a382611964565b602082019050919050565b5f6020820190508181035f8301526119c58161198c565b9050919050565b7f45524332303a206275726e2066726f6d206d6f64756c652061646472657373005f82015250565b5f611a00601f836114a3565b9150611a0b826119cc565b602082019050919050565b5f6020820190508181035f830152611a2d816119f4565b9050919050565b5f611a3e82611583565b9150611a4983611583565b9250828201905080821115611a6157611a60611904565b5b9291505056fea2646970667358221220de4043b1adb87162ffc06c0127fc335d705e04b467c9acd7522c8721ebd4c4bb64736f6c63430008190033a264697066735822122022aae101fc4d9117c6c01e16ed9c8ac00cda01b5c25b244220cdec4e3894707a64736f6c63430008190033", } // Erc20WrapperABI is the input ABI used to generate the binding from. diff --git a/x/evm/contracts/erc20_wrapper/ERC20Wrapper.sol b/x/evm/contracts/erc20_wrapper/ERC20Wrapper.sol index 6b8c9b7..f4f79f0 100644 --- a/x/evm/contracts/erc20_wrapper/ERC20Wrapper.sol +++ b/x/evm/contracts/erc20_wrapper/ERC20Wrapper.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.24; -import "../util/Strings.sol"; +import "../strings/Strings.sol"; import "../i_cosmos/ICosmos.sol"; import "../erc20_factory/ERC20Factory.sol"; import "../i_erc20/IERC20.sol"; diff --git a/x/evm/contracts/strings/Strings.go b/x/evm/contracts/strings/Strings.go new file mode 100644 index 0000000..0d8a864 --- /dev/null +++ b/x/evm/contracts/strings/Strings.go @@ -0,0 +1,203 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package strings + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// StringsMetaData contains all meta data concerning the Strings contract. +var StringsMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"length\",\"type\":\"uint256\"}],\"name\":\"StringsInsufficientHexLength\",\"type\":\"error\"}]", + Bin: "0x6055604b600b8282823980515f1a607314603f577f4e487b71000000000000000000000000000000000000000000000000000000005f525f60045260245ffd5b305f52607381538281f3fe730000000000000000000000000000000000000000301460806040525f80fdfea2646970667358221220435189e60bca7f1d36c26a4ebe73537def258e153b95e8cee658620453c34e6364736f6c63430008190033", +} + +// StringsABI is the input ABI used to generate the binding from. +// Deprecated: Use StringsMetaData.ABI instead. +var StringsABI = StringsMetaData.ABI + +// StringsBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use StringsMetaData.Bin instead. +var StringsBin = StringsMetaData.Bin + +// DeployStrings deploys a new Ethereum contract, binding an instance of Strings to it. +func DeployStrings(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *Strings, error) { + parsed, err := StringsMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(StringsBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &Strings{StringsCaller: StringsCaller{contract: contract}, StringsTransactor: StringsTransactor{contract: contract}, StringsFilterer: StringsFilterer{contract: contract}}, nil +} + +// Strings is an auto generated Go binding around an Ethereum contract. +type Strings struct { + StringsCaller // Read-only binding to the contract + StringsTransactor // Write-only binding to the contract + StringsFilterer // Log filterer for contract events +} + +// StringsCaller is an auto generated read-only Go binding around an Ethereum contract. +type StringsCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// StringsTransactor is an auto generated write-only Go binding around an Ethereum contract. +type StringsTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// StringsFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type StringsFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// StringsSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type StringsSession struct { + Contract *Strings // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// StringsCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type StringsCallerSession struct { + Contract *StringsCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// StringsTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type StringsTransactorSession struct { + Contract *StringsTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// StringsRaw is an auto generated low-level Go binding around an Ethereum contract. +type StringsRaw struct { + Contract *Strings // Generic contract binding to access the raw methods on +} + +// StringsCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type StringsCallerRaw struct { + Contract *StringsCaller // Generic read-only contract binding to access the raw methods on +} + +// StringsTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type StringsTransactorRaw struct { + Contract *StringsTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewStrings creates a new instance of Strings, bound to a specific deployed contract. +func NewStrings(address common.Address, backend bind.ContractBackend) (*Strings, error) { + contract, err := bindStrings(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &Strings{StringsCaller: StringsCaller{contract: contract}, StringsTransactor: StringsTransactor{contract: contract}, StringsFilterer: StringsFilterer{contract: contract}}, nil +} + +// NewStringsCaller creates a new read-only instance of Strings, bound to a specific deployed contract. +func NewStringsCaller(address common.Address, caller bind.ContractCaller) (*StringsCaller, error) { + contract, err := bindStrings(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &StringsCaller{contract: contract}, nil +} + +// NewStringsTransactor creates a new write-only instance of Strings, bound to a specific deployed contract. +func NewStringsTransactor(address common.Address, transactor bind.ContractTransactor) (*StringsTransactor, error) { + contract, err := bindStrings(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &StringsTransactor{contract: contract}, nil +} + +// NewStringsFilterer creates a new log filterer instance of Strings, bound to a specific deployed contract. +func NewStringsFilterer(address common.Address, filterer bind.ContractFilterer) (*StringsFilterer, error) { + contract, err := bindStrings(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &StringsFilterer{contract: contract}, nil +} + +// bindStrings binds a generic wrapper to an already deployed contract. +func bindStrings(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := StringsMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Strings *StringsRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Strings.Contract.StringsCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_Strings *StringsRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Strings.Contract.StringsTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_Strings *StringsRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Strings.Contract.StringsTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Strings *StringsCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Strings.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_Strings *StringsTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Strings.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_Strings *StringsTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Strings.Contract.contract.Transact(opts, method, params...) +} diff --git a/x/evm/contracts/util/Strings.sol b/x/evm/contracts/strings/Strings.sol similarity index 83% rename from x/evm/contracts/util/Strings.sol rename to x/evm/contracts/strings/Strings.sol index 415c5a2..2884d8d 100644 --- a/x/evm/contracts/util/Strings.sol +++ b/x/evm/contracts/strings/Strings.sol @@ -10,6 +10,7 @@ library Strings { */ error StringsInsufficientHexLength(uint256 value, uint256 length); + // uint256 to hex string function toHexString( uint256 value, uint256 length @@ -28,6 +29,19 @@ library Strings { return string(buffer); } + // bytes to hex string + function toHexString(bytes memory buffer) internal pure returns (string memory) { + bytes memory converted = new bytes(buffer.length * 2); + bytes memory _base = "0123456789abcdef"; + + for (uint256 i = 0; i < buffer.length; i++) { + converted[i * 2] = _base[uint8(buffer[i]) / _base.length]; + converted[i * 2 + 1] = _base[uint8(buffer[i]) % _base.length]; + } + + return string(abi.encodePacked("0x", converted)); + } + function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), ADDRESS_LENGTH); } diff --git a/x/evm/contracts/util/Strings.go b/x/evm/contracts/util/Strings.go deleted file mode 100644 index 4424517..0000000 --- a/x/evm/contracts/util/Strings.go +++ /dev/null @@ -1,203 +0,0 @@ -// Code generated - DO NOT EDIT. -// This file is a generated binding and any manual changes will be lost. - -package util - -import ( - "errors" - "math/big" - "strings" - - ethereum "github.com/ethereum/go-ethereum" - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/event" -) - -// Reference imports to suppress errors if they are not otherwise used. -var ( - _ = errors.New - _ = big.NewInt - _ = strings.NewReader - _ = ethereum.NotFound - _ = bind.Bind - _ = common.Big1 - _ = types.BloomLookup - _ = event.NewSubscription - _ = abi.ConvertType -) - -// UtilMetaData contains all meta data concerning the Util contract. -var UtilMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"length\",\"type\":\"uint256\"}],\"name\":\"StringsInsufficientHexLength\",\"type\":\"error\"}]", - Bin: "0x6055604b600b8282823980515f1a607314603f577f4e487b71000000000000000000000000000000000000000000000000000000005f525f60045260245ffd5b305f52607381538281f3fe730000000000000000000000000000000000000000301460806040525f80fdfea2646970667358221220c8a20e32684b8eb475517477c61e8fbe77e3c5335efa1a66ec78960a607261e064736f6c63430008190033", -} - -// UtilABI is the input ABI used to generate the binding from. -// Deprecated: Use UtilMetaData.ABI instead. -var UtilABI = UtilMetaData.ABI - -// UtilBin is the compiled bytecode used for deploying new contracts. -// Deprecated: Use UtilMetaData.Bin instead. -var UtilBin = UtilMetaData.Bin - -// DeployUtil deploys a new Ethereum contract, binding an instance of Util to it. -func DeployUtil(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *Util, error) { - parsed, err := UtilMetaData.GetAbi() - if err != nil { - return common.Address{}, nil, nil, err - } - if parsed == nil { - return common.Address{}, nil, nil, errors.New("GetABI returned nil") - } - - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(UtilBin), backend) - if err != nil { - return common.Address{}, nil, nil, err - } - return address, tx, &Util{UtilCaller: UtilCaller{contract: contract}, UtilTransactor: UtilTransactor{contract: contract}, UtilFilterer: UtilFilterer{contract: contract}}, nil -} - -// Util is an auto generated Go binding around an Ethereum contract. -type Util struct { - UtilCaller // Read-only binding to the contract - UtilTransactor // Write-only binding to the contract - UtilFilterer // Log filterer for contract events -} - -// UtilCaller is an auto generated read-only Go binding around an Ethereum contract. -type UtilCaller struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// UtilTransactor is an auto generated write-only Go binding around an Ethereum contract. -type UtilTransactor struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// UtilFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type UtilFilterer struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// UtilSession is an auto generated Go binding around an Ethereum contract, -// with pre-set call and transact options. -type UtilSession struct { - Contract *Util // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// UtilCallerSession is an auto generated read-only Go binding around an Ethereum contract, -// with pre-set call options. -type UtilCallerSession struct { - Contract *UtilCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session -} - -// UtilTransactorSession is an auto generated write-only Go binding around an Ethereum contract, -// with pre-set transact options. -type UtilTransactorSession struct { - Contract *UtilTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// UtilRaw is an auto generated low-level Go binding around an Ethereum contract. -type UtilRaw struct { - Contract *Util // Generic contract binding to access the raw methods on -} - -// UtilCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type UtilCallerRaw struct { - Contract *UtilCaller // Generic read-only contract binding to access the raw methods on -} - -// UtilTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type UtilTransactorRaw struct { - Contract *UtilTransactor // Generic write-only contract binding to access the raw methods on -} - -// NewUtil creates a new instance of Util, bound to a specific deployed contract. -func NewUtil(address common.Address, backend bind.ContractBackend) (*Util, error) { - contract, err := bindUtil(address, backend, backend, backend) - if err != nil { - return nil, err - } - return &Util{UtilCaller: UtilCaller{contract: contract}, UtilTransactor: UtilTransactor{contract: contract}, UtilFilterer: UtilFilterer{contract: contract}}, nil -} - -// NewUtilCaller creates a new read-only instance of Util, bound to a specific deployed contract. -func NewUtilCaller(address common.Address, caller bind.ContractCaller) (*UtilCaller, error) { - contract, err := bindUtil(address, caller, nil, nil) - if err != nil { - return nil, err - } - return &UtilCaller{contract: contract}, nil -} - -// NewUtilTransactor creates a new write-only instance of Util, bound to a specific deployed contract. -func NewUtilTransactor(address common.Address, transactor bind.ContractTransactor) (*UtilTransactor, error) { - contract, err := bindUtil(address, nil, transactor, nil) - if err != nil { - return nil, err - } - return &UtilTransactor{contract: contract}, nil -} - -// NewUtilFilterer creates a new log filterer instance of Util, bound to a specific deployed contract. -func NewUtilFilterer(address common.Address, filterer bind.ContractFilterer) (*UtilFilterer, error) { - contract, err := bindUtil(address, nil, nil, filterer) - if err != nil { - return nil, err - } - return &UtilFilterer{contract: contract}, nil -} - -// bindUtil binds a generic wrapper to an already deployed contract. -func bindUtil(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := UtilMetaData.GetAbi() - if err != nil { - return nil, err - } - return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_Util *UtilRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Util.Contract.UtilCaller.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_Util *UtilRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Util.Contract.UtilTransactor.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_Util *UtilRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Util.Contract.UtilTransactor.contract.Transact(opts, method, params...) -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_Util *UtilCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Util.Contract.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_Util *UtilTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Util.Contract.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_Util *UtilTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Util.Contract.contract.Transact(opts, method, params...) -} diff --git a/x/evm/keeper/common_test.go b/x/evm/keeper/common_test.go index f9ca0da..adf2133 100644 --- a/x/evm/keeper/common_test.go +++ b/x/evm/keeper/common_test.go @@ -278,6 +278,9 @@ func _createTestInput( }, ) + // register evm message service to the router + evmtypes.RegisterMsgServer(msgRouter, evmkeeper.NewMsgServerImpl(evmKeeper)) + // set erc20 keeper *erc20Keeper = *evmKeeper.ERC20Keeper().(*evmkeeper.ERC20Keeper) faucet := NewTestFaucet(t, ctx, bankKeeper, authtypes.Minter) diff --git a/x/evm/keeper/context_test.go b/x/evm/keeper/context_test.go index 6112725..1f5e3b5 100644 --- a/x/evm/keeper/context_test.go +++ b/x/evm/keeper/context_test.go @@ -187,3 +187,35 @@ func Test_GetHash(t *testing.T) { require.Equal(t, [32]byte{}, [32]byte(queryRes)) require.Empty(t, logs) } + +func Test_RecursiveDepth(t *testing.T) { + ctx, input := createDefaultTestInput(t) + _, _, addr := keyPubAddr() + + counterBz, err := hexutil.Decode(counter.CounterBin) + require.NoError(t, err) + + // deploy counter contract + caller := common.BytesToAddress(addr.Bytes()) + retBz, contractAddr, _, err := input.EVMKeeper.EVMCreate(ctx, caller, counterBz, nil, nil) + require.NoError(t, err) + require.NotEmpty(t, retBz) + require.Len(t, contractAddr, 20) + + // call recursive function + parsed, err := counter.CounterMetaData.GetAbi() + require.NoError(t, err) + + inputBz, err := parsed.Pack("recursive", uint64(types.MAX_RECURSIVE_DEPTH-1)) + require.NoError(t, err) + + _, _, err = input.EVMKeeper.EVMCall(ctx, caller, contractAddr, inputBz, nil, nil) + require.NoError(t, err) + + // exceed max recursive depth + inputBz, err = parsed.Pack("recursive", uint64(types.MAX_RECURSIVE_DEPTH)) + require.NoError(t, err) + + _, _, err = input.EVMKeeper.EVMCall(ctx, caller, contractAddr, inputBz, nil, nil) + require.ErrorContains(t, err, types.ErrExceedMaxRecursiveDepth.Error()) +} diff --git a/x/evm/keeper/msg_server.go b/x/evm/keeper/msg_server.go index 26dffd4..45aa5c7 100644 --- a/x/evm/keeper/msg_server.go +++ b/x/evm/keeper/msg_server.go @@ -187,8 +187,9 @@ func (ms *msgServerImpl) Call(ctx context.Context, msg *types.MsgCall) (*types.M if overflow { return nil, types.ErrInvalidValue.Wrap("value is out of range") } + accessList := types.ConvertCosmosAccessListToEth(msg.AccessList) - retBz, logs, err := ms.EVMCall(ctx, caller, contractAddr, inputBz, value, nil) + retBz, logs, err := ms.EVMCall(ctx, caller, contractAddr, inputBz, value, accessList) if err != nil { return nil, types.ErrEVMCallFailed.Wrap(err.Error()) } diff --git a/x/evm/types/params.go b/x/evm/types/params.go index 9d5735a..88c30d7 100644 --- a/x/evm/types/params.go +++ b/x/evm/types/params.go @@ -9,7 +9,7 @@ import ( ) // MAX_RECURSIVE_DEPTH is the maximum depth of the x/evm call stack. -const MAX_RECURSIVE_DEPTH = 16 +const MAX_RECURSIVE_DEPTH = 8 func DefaultParams() Params { return Params{