From f9845167c3cf6149cddb0e70bfb991145951b2e8 Mon Sep 17 00:00:00 2001 From: Matias Volpe Date: Mon, 12 Dec 2022 11:55:18 -0300 Subject: [PATCH 01/21] feat: add smart contract example --- deps/std/encoding/base58.ts | 3 +- effects/events.ts | 5 +- effects/rpc_known_clients.ts | 1 + effects/rpc_known_methods.ts | 1 + examples/smart_contract.ts | 159 +++++++++++++++++++++++ examples/smart_contract/codec.ts | 48 +++++++ examples/smart_contract/flipper.contract | 1 + examples/smart_contract/flipper.wasm | Bin 0 -> 15044 bytes examples/smart_contract/metadata.json | 108 +++++++++++++++ 9 files changed, 324 insertions(+), 2 deletions(-) create mode 100644 examples/smart_contract.ts create mode 100644 examples/smart_contract/codec.ts create mode 100644 examples/smart_contract/flipper.contract create mode 100644 examples/smart_contract/flipper.wasm create mode 100644 examples/smart_contract/metadata.json diff --git a/deps/std/encoding/base58.ts b/deps/std/encoding/base58.ts index e94d0fdd6..66333c9b0 100644 --- a/deps/std/encoding/base58.ts +++ b/deps/std/encoding/base58.ts @@ -1 +1,2 @@ -export * from "https://deno.land/std@0.154.0/encoding/base58.ts" +// export * from "https://deno.land/std@0.167.0/encoding/base58.ts" +export * from "https://raw.githubusercontent.com/kratico/deno_std/main/encoding/base58.ts" diff --git a/effects/events.ts b/effects/events.ts index 6bb3be7c8..59661b662 100644 --- a/effects/events.ts +++ b/effects/events.ts @@ -24,7 +24,10 @@ export function events() + .as<{ + event?: Record + phase: { value: number } + }[]>() return Z .ls(idx, events) .next(([idx, events]) => { diff --git a/effects/rpc_known_clients.ts b/effects/rpc_known_clients.ts index 166565742..8ffd8bb41 100644 --- a/effects/rpc_known_clients.ts +++ b/effects/rpc_known_clients.ts @@ -14,3 +14,4 @@ export const moonbeam = proxyClient("wss://wss.api.moonbeam.network") export const statemint = proxyClient("wss://statemint-rpc.polkadot.io") export const subsocial = proxyClient("wss://para.subsocial.network") export const westend = proxyClient("wss://westend-rpc.polkadot.io") +export const local = proxyClient("ws://127.0.0.1:9944") diff --git a/effects/rpc_known_methods.ts b/effects/rpc_known_methods.ts index 0092b1452..f83d55729 100644 --- a/effects/rpc_known_methods.ts +++ b/effects/rpc_known_methods.ts @@ -5,6 +5,7 @@ import { rpcCall, rpcSubscription } from "./rpc.ts" // TODO: generate the following? export namespace state { export const getMetadata = rpcCall<[at?: U.HexHash], U.HexHash>("state_getMetadata") + export const call = rpcCall<[method: string, data: U.Hex], U.HexHash>("state_call") export const getStorage = rpcCall< [key: known.StorageKey, at?: U.HexHash], known.StorageData diff --git a/examples/smart_contract.ts b/examples/smart_contract.ts new file mode 100644 index 000000000..d2d789823 --- /dev/null +++ b/examples/smart_contract.ts @@ -0,0 +1,159 @@ +import * as C from "http://localhost:5646/@local/mod.ts" +import * as T from "http://localhost:5646/@local/test_util/mod.ts" +import * as U from "http://localhost:5646/@local/util/mod.ts" + +import { $contractsApiCallArgs, $contractsApiCallReturn } from "./smart_contract/codec.ts" + +const contract = await getContract( + "./examples/smart_contract/flipper.wasm", + "./examples/smart_contract/metadata.json", +) + +const contractAddress = U.throwIfError(await instantiateContractTx().run()) +console.log("Deployed Contract address", U.ss58.encode(42, contractAddress)) +console.log("get message", U.throwIfError(await sendGetMessage(contractAddress).run())) +console.log("flip message in block", U.throwIfError(await sendFlipMessage(contractAddress).run())) +console.log("get message", U.throwIfError(await sendGetMessage(contractAddress).run())) + +function instantiateContractTx() { + const constructor = findContractConstructorByLabel("default")! + const tx = C.extrinsic(C.local)({ + sender: T.alice.address, + call: { + type: "Contracts", + value: { + type: "instantiateWithCode", + value: 0n, + // TODO: create sendDryRunContractInitiate and fetch these gasLimit value + gasLimit: { + refTime: 200_000_000_000n, + proofSize: 0n, + }, + storageDepositLimit: undefined, + code: contract.wasm, + data: U.hex.decode(constructor.selector), + salt: Uint8Array.from(Array.from([0, 0, 0, 0]), () => Math.floor(Math.random() * 16)), + }, + }, + }) + .signed(T.alice.sign) + const finalizedIn = tx.watch(({ end }) => + (status) => { + // .watch emits a single inBlock event + if (typeof status !== "string" && status.inBlock) { + return end(status.inBlock) + } else if (C.rpc.known.TransactionStatus.isTerminal(status)) { + return end(new Error()) + } + return + } + ) + return C.events(tx, finalizedIn).next((events) => { + const event = events.find((e) => + e.event?.type === "Contracts" && e.event?.value?.type === "Instantiated" + ) + return event?.event?.value.contract as Uint8Array + }) +} + +function sendMessageDryRunContractCall( + address: Uint8Array, + message: C.M.ContractMetadata.Message | C.M.ContractMetadata.Constructor, +) { + const key = U.hex.encode($contractsApiCallArgs.encode([ + T.alice.publicKey, + address, + 0n, + undefined, + undefined, + U.hex.decode(message.selector), + ])) + return C.state.call(C.local)( + "ContractsApi_call", + key, + ) + .next((encodedResponse) => { + return $contractsApiCallReturn.decode(U.hex.decode(encodedResponse)) + }) +} + +function sendGetMessage(address: Uint8Array) { + const message = findContractMessageByLabel("get")! + const key = U.hex.encode($contractsApiCallArgs.encode([ + T.alice.publicKey, + address, + 0n, + undefined, + undefined, + U.hex.decode(message.selector), + ])) + return C.state.call(C.local)( + "ContractsApi_call", + key, + ) + .next((encodedResponse) => { + const response = $contractsApiCallReturn.decode(U.hex.decode(encodedResponse)) + if (message.returnType.type === null) { + return undefined + } + return contract.deriveCodec(message.returnType.type).decode(response.result.data) + }) +} + +function sendFlipMessage(address: Uint8Array) { + const message = findContractMessageByLabel("flip")! + const value = sendMessageDryRunContractCall(address, message) + .next(({ gas_required }) => { + return { + type: "call", + dest: C.MultiAddress.Id(address), + value: 0n, + data: U.hex.decode(message.selector), + gasLimit: { + refTime: gas_required.ref_time, + proofSize: gas_required.proof_size, + }, + storageDepositLimit: undefined, + } + }) + return C.extrinsic(C.local)({ + sender: T.alice.address, + call: C.Z.rec({ + type: "Contracts", + value, + }), + }) + .signed(T.alice.sign) + .watch(({ end }) => + (status) => { + // .watch emits a single inBlock event + if (typeof status !== "string" && status.inBlock) { + return end(status.inBlock) + } else if (C.rpc.known.TransactionStatus.isTerminal(status)) { + return end(new Error()) + } + return + } + ) +} + +function findContractConstructorByLabel(label: string) { + return contract.metadata.V3.spec.constructors.find((c) => c.label === label) +} + +function findContractMessageByLabel(label: string) { + return contract.metadata.V3.spec.messages.find((c) => c.label === label) +} + +async function getContract(wasmFile: string, metadataFile: string) { + const wasm = await Deno.readFile(wasmFile) + const metadata = C.M.ContractMetadata.normalize(JSON.parse( + await Deno.readTextFile(metadataFile), + )) + const deriveCodec = C.M.DeriveCodec(metadata.V3.types) + return { + wasm, + metadata, + deriveCodec, + } +} diff --git a/examples/smart_contract/codec.ts b/examples/smart_contract/codec.ts new file mode 100644 index 000000000..8081d6533 --- /dev/null +++ b/examples/smart_contract/codec.ts @@ -0,0 +1,48 @@ +import * as C from "http://localhost:5646/@local/mod.ts" + +const $balanceCodec = C.$.u128 +const $weightCodec = C.$.object( + ["ref_time", C.$.compact(C.$.u64)], + ["proof_size", C.$.compact(C.$.u64)], +) + +export const $contractsApiCallArgs = C.$.tuple( + // origin + C.$.sizedUint8Array(32), + // dest + C.$.sizedUint8Array(32), + // balance + $balanceCodec, + // weight + C.$.option($weightCodec), + // storage_deposit_limit + C.$.option($balanceCodec), + // data + C.$.uint8Array, +) + +export const $contractsApiCallReturn = C.$.object( + // gas_consumed + ["gas_consumed", $weightCodec], + // gas_required + ["gas_required", $weightCodec], + // storage_deposit + [ + "storage_deposit", + C.$.taggedUnion("type", [ + ["Refund", ["value", $balanceCodec]], + ["Charge", ["value", $balanceCodec]], + ]), + ], + // debug_message + ["debug_message", C.$.str], + // result + [ + "result", + C.$.object( + ["flags", C.$.u32], + // TODO: improve result error coded + ["data", C.$.result(C.$.uint8Array, C.$.never)], + ), + ], +) diff --git a/examples/smart_contract/flipper.contract b/examples/smart_contract/flipper.contract new file mode 100644 index 000000000..7b5e7984e --- /dev/null +++ b/examples/smart_contract/flipper.contract @@ -0,0 +1 @@ +{"source":{"hash":"0x2345709e061bfa0d374eaf0c25f19c8dce43ac11362c55196e1ecf465781b750","language":"ink! 3.4.0","compiler":"rustc 1.67.0-nightly","wasm":"0x0061736d01000000014e0d60037f7f7f017f60027f7f017f60027f7f0060057f7f7f7f7f0060037f7f7f0060047f7f7f7f0060017f0060000060047f7f7f7f017f60017f017e60017f017f6000017f60067f7f7f7f7f7f0002a30107057365616c30127365616c5f64656275675f6d6573736167650001057365616c30107365616c5f7365745f73746f726167650004057365616c30107365616c5f6765745f73746f726167650000057365616c300a7365616c5f696e7075740002057365616c300b7365616c5f72657475726e0004057365616c30167365616c5f76616c75655f7472616e73666572726564000203656e76066d656d6f727902010210033b3a0002010601020a00020303040b02070607030100000401010006070206010903050101010308050803040101040000030508050101010101050c040501700110100501000608017f01418080040b071102066465706c6f7900140463616c6c00160915010041010b0f0a30313c2723393a223d1a1c1d3b240acf513a2b01017f037f2002200346047f200005200020036a200120036a2d00003a0000200341016a21030c010b0b0b7901017f230041406a22022400200241206a200141186a290000370300200241186a200141106a290000370300200241106a200141086a29000037030020024201370328200220012900003703082002419ea104360230200242808001370234200241086a200241306a2000100841011001200241406b24000b7701037f230041106b220224002000280204210320002802002104200220013a000f200241012004200341c49a04100f200228020020022802042002410f6a410141d49a041010200345044041a49904412341e49a041011000b2000200341016b3602042000200441016a360200200241106a240020040b5201017f230041206b220124002001410c6a4101360200200141146a4101360200200141909d04360208200141003602002001410136021c200120003602182001200141186a360210200141948304100b000b910101017f230041306b22022400200241146a41013602002002411c6a4101360200200241909d043602102002410036020820024102360224200220002d0000410274220041eca0046a28020036022c200220004180a1046a280200360228200141046a28020021002002200241206a3602182002200241286a36022020012802002000200241086a1033200241306a24000b840301037f230041206b22032400200341013a00182003200136021420032000360210200341dc890436020c200341909d04360208230041406a220224002002200341086a36020c2002410436022420022002410c6a360220410021004104210402400240024002400240024003402000200441c899046a2802006a22012000490d0120012100200441086a22044114470d000b4100210041012104024020014110490d002001200120016a22034b200345720d0020034100480d022002200310212003210020022802002204450d060b2002410036021820022004360214200220003602102002410136023c20024102360234200241c89904360230200241003602282002200241206a360238200241106a200241286a10180d02419ca1042d0000450440419da1042d00004101710d060b2002280214200228021810004109470d030c040b41c08404411c418499041011000b1020000b41c086044133200241286a4184850441e087041017000b419ca10441013a00000b419da10441013a00000b000b4001017f230041106b22012400200141003a000f20002001410f6a4101100d047f4102054101410220012d000f22004101461b410020001b0b200141106a24000b6001047f230041106b22032400200028020422042002492205450440200341086a4100200220002802002206103e200120022003280208200328020c41a4a00410102003200220042006103e200020032903003702000b200341106a240020050b4701017f230041106b220224002002410036020c024020012002410c6a4104100d4504402000200228020c360001200041003a00000c010b200041013a00000b200241106a24000b2200200120034d044020002001360204200020023602000f0b200120032004102f000b8501002001200346044020002002200110061a0f0b230041306b220024002000200336020420002001360200200041146a41033602002000411c6a41023602002000412c6a4105360200200041ec920436021020004100360208200041053602242000200041206a360218200020003602282000200041046a360220200041086a2004100b000b5001017f230041206b220324002003410c6a4101360200200341146a4100360200200341909d04360210200341003602002003200136021c200320003602182003200341186a36020820032002100b000b6c02027f027e230041206b22002400200041086a220142003703002000420037030020004110360214200020003602102000411036021c20002000411c6a1005200041106a200028021c10132001290300210220002903002103200041206a2400410541042002200384501b0b3501017f230041106b22022400200241086a20012000280200200028020441dc9b04100f20002002290308370200200241106a24000bd00301057f230041306b220024002000027f02400240101241ff0171410546044020004180800136022c2000419ea104360228200041286a1015200020002903283703082000200041086a100e20002d00000d022000280001220141187621022001411076210320014108762104027f200141ff01712201419b01470440200141ed0147200441ff017141cb004772200341ff0171419d0147720d0441022002411b460d011a0c040b200441ff017141ae0147200341ff0171419d014772200241de0047720d03200041086a100c41ff017122014102460d0320014101710b2101101241ff01712102024002402001410247044020024105460d010c040b20024105470d03200041206a4200370300200041186a4200370300200041106a4200370300200042003703084100200041086a10070c010b200041206a4200370300200041186a4200370300200041106a4200370300200042003703082001200041086a10070b200041306a24000f0b200041043a0008200041086a1009000b41040c010b41030b3a0000200041146a41013602002000411c6a4101360200200041ec8304360210200041003602082000410136022c2000200041286a36021820002000360228200041086a41948304100b000b3301017f230041106b220124002001200028020436020c20002802002001410c6a10032000200128020c1013200141106a24000b8a0601057f230041d0006b2200240002400240024002400240101241ff01712201410546044020004180800136023c2000419ea104360238200041386a101520002000290338370308200041306a200041086a100e024020002d00300d002000280031220141187621022001411076210320014108762104200141ff01712201412f470440200141e30047200441ff0171413a4772200341ff017141a50147720d0141012101200241d100470d010c030b200441ff017141860147200341ff017141db0047720d0041002101200241d901460d020b410321010c020b200020013a0008200041086a1009000b200041106a4200370300200041186a4200370300200041206a420037030020004200370308200042013703282000418080013602342000419ea104360230200041808001360238200041086a419ea104200041386a10022102200041306a200028023810130240024002402002410c4f0d00200241027441bca0046a2802000e0402000001000b200041c4006a4101360200200041cc006a4100360200200041d48204360240200041909d0436024820004100360238200041386a41dc8204100b000b230041106b220124002001411736020c200141988104360208230041206b220024002000410c6a4101360200200041146a4101360200200041909d04360208200041003602002000410236021c2000200141086a3602182000200041186a360210200041b08104100b000b20002000290330370338200041386a100c41ff017122024102460d03101241ff017121032001044020034105460d02410421010c010b4104210120034105460d020b200020013a0030200041146a41013602002000411c6a4101360200200041988404360210200041003602082000410136023c2000200041386a3602182000200041306a360238200041086a41948304100b000b20024541a483041007200041d0006a24000f0b230041106b220024002000419ea104360200200042808001370204410020002002410047100841011004000b200041003a0038418080044127200041386a41c08104418881041017000b860101017f230041406a220524002005200136020c200520003602082005200336021420052002360210200541246a41023602002005412c6a41023602002005413c6a4103360200200541908a0436022020054100360218200541023602342005200541306a3602282005200541106a3602382005200541086a360230200541186a2004100b000b5501017f230041206b2202240020022000360204200241186a200141106a290200370300200241106a200141086a29020037030020022001290200370308200241046a41a08404200241086a1019200241206a24000bee0301057f230041406a22032400200341033a003820034280808080800437033020034100360228200341003602202003200136021c20032000360218027f0240024020022802002201450440200241146a28020022004103742105200041ffffffff017121072002280210210441002101034020012005460d02200228020820016a220041046a28020022060440200328021820002802002006200328021c28020c1100000d040b200141086a2101200428020020042802042106200441086a2104200341186a2006110100450d000b0c020b200228020422074105742100200741ffffff3f71210703402000450d01200228020820046a220541046a28020022060440200328021820052802002006200328021c28020c1100000d030b20032001411c6a2d00003a00382003200141146a290200370330200341106a200228021022052001410c6a103220032003290310370320200341086a2005200141046a103220032003290308370328200441086a2104200041206b210020012802002106200141206a2101200520064103746a2205280200200341186a2005280204110100450d000b0c010b2002410c6a28020020074b04402003280218200228020820074103746a22002802002000280204200328021c28020c1100000d010b41000c010b41010b200341406b24000b0f00200028020020012002101b41000b5801017f20022000280200200028020822036b4b0440200020032002101e101f200028020821030b200028020420036a2001200210061a2003200220036a22014b044041c08404411c41f088041011000b200020013602080bbe0201027f230041106b220224000240024002400240200028020022002002410c6a027f0240024020014180014f04402002410036020c2001418010490d012001418080044f0d0220022001413f71418001723a000e20022001410c7641e001723a000c20022001410676413f71418001723a000d41030c030b200028020822032000280200460d030c040b20022001413f71418001723a000d2002200141067641c001723a000c41020c010b20022001413f71418001723a000f20022001410676413f71418001723a000e20022001410c76413f71418001723a000d2002200141127641077141f001723a000c41040b101b0c020b200020034101101e101f200028020821030b200028020420036a20013a0000200341016a2201450d01200020013602080b200241106a240041000f0b41c08404411c41e088041011000b4a01017f230041206b220224002000280200200241186a200141106a290200370300200241106a200141086a29020037030020022001290200370308200241086a1018200241206a24000b990401067f230041206b220324000240027f41002001200120026a22014b0d001a2000280200220220026a22052002490d012005200120012005491b22014108200141084b1b2201417f73411f7621040240200204402003410136021820032002360214200320002802043602100c010b200341003602180b200341106a2106230041106b220524002003027f0240027f0240200404400240200141004e044020062802080d012005200110212005280204210220052802000c040b0c040b20062802042208450440200541086a20011021200528020c210220052802080c030b2001210241004194a104280200220420016a22072004490d021a200628020021064198a1042802002007490440200141ffff036a220741107640002202417f46200241ffff0371200247720d022002411074220420074180807c716a22022004490d024198a1042002360200200121024100200120046a22072004490d031a0b4194a104200736020041002004450d021a20042006200810060c020b200320013602040c020b2001210241000b2204044020032004360204200341086a200236020041000c020b20032001360204200341086a410136020041010c010b200341086a410036020041010b360200200541106a240020032802004504402003280204210220002001360200200020023602044181808080780c010b200341086a2802000b200341206a24000f0b41e084044121418486041011000b1b00024020004181808080784704402000450d01000b0f0b1020000b4601017f230041206b22002400200041146a41013602002000411c6a4100360200200041a88604360210200041909d0436021820004100360208200041086a41b08604100b000ba10101027f027f41004194a104280200220320016a22022003490d001a02404198a1042802002002490440200141ffff036a22022001490d012002411076220240002203417f46200341ffff0371200347720d012003411074220320024110746a22022003490d014198a10420023602004100200120036a22022003490d021a0b4194a104200236020020030c010b41000b210220002001360204200020023602000b0300010b0e0020002802001a03400c000b000b0c0042abf2ce83adf3f7da440bb20101017f230041106b2205240020022003490440230041306b220024002000200236020420002003360200200041146a41023602002000411c6a41023602002000412c6a4105360200200041e88f0436021020004100360208200041053602242000200041206a3602182000200041046a36022820002000360220200041086a2004100b000b200541086a2003200220011026200528020c21012000200528020836020020002001360204200541106a24000b1400200020012002200341849f0441a08904103f0bd806020b7f027e230041406a2203240020002802002202ad210d0240024002400240024002400240024020024190ce004f044041272100200d210e0240034020004104490d01200341196a20006a220241046b200e200e4290ce0080220d4290ce007e7da7220441ffff037141e4006e220641017441978b046a2f00003b0000200241026b2004200641e4006c6b41ffff037141017441978b046a2f00003b0000200041046b2100200e42ffc1d72f56200d210e0d000b200da7220241e3004d0d0320004102490d090c020b0c080b41272100200241e3004b0d002002410a490d040c020b200041026b2200200341196a6a200da72202200241ffff037141e4006e220241e4006c6b41ffff037141017441978b046a2f00003b00000b2002410a490d01200041024f0d000c050b200041026b2200200341196a6a200241017441978b046a2f00003b00000c020b2000450d030b200041016b2200200341196a6a200241306a3a00000b200041274b0d01412820006b412720006b22062001280218220541017122071b2102410021042005410471044041909d042104200241909d0441909d04102820026a22024b0d010b412b418080c40020071b2107200341196a20006a2108024020012802084504404101210020012802002202200141046a280200220120072004102b0d01200220082006200128020c11000021000c010b024020022001410c6a28020022094904402005410871450d01200128021c210b2001413036021c20012d0020210c41012100200141013a002020012802002205200141046a280200220a20072004102b0d02200341106a2001200920026b4101102c20032802142202418080c400460d022003280210200520082006200a28020c1100000d0220022005200a102d0d022001200c3a00202001200b36021c410021000c020b4101210020012802002202200141046a280200220120072004102b0d01200220082006200128020c11000021000c010b41012100200341086a2001200920026b4101102c200328020c2205418080c400460d00200328020820012802002202200141046a280200220120072004102b0d00200220082006200128020c1100000d00200520022001102d21000b200341406b240020000f0b41808904411c41d08d041011000b41a089044121419499041011000ba704010a7f230041106b2203240002400240200020016b22024110490d002002200141036a417c7120016b220049200041044b720d00200220006b22044104490d002001200010292206200020016a22082004417c716a200441037110296a220220064f0440200441027621050240024003402005450d05200320082005200541c001200541c001491b418c9104102a200328020c21052003280208210820032003280200200328020422002000417c71418c9204102a200328020c210920032802082107024020032802042200450440410021010c010b2003280200220420004102746a210a4100210103402004220641106a2104410021000240034020012001200020066a280200220b417f73410776200b410676724181828408716a22014d0440200041046a22004110470d010c020b0b41808904411c418494041011000b2004200a470d000b0b20022002200141087641ff81fc0771200141ff81fc07716a418180046c4110766a22024b0d012009450d000b200941027421004100210103402001200120072802002204417f734107762004410676724181828408716a22014b0d02200741046a2107200041046b22000d000b20022002200141087641ff81fc0771200141ff81fc07716a418180046c4110766a22024d0d0441808904411c41b494041011000b41808904411c419494041011000b41808904411c41a494041011000b41808904411c41f493041011000b20012002102921020b200341106a240020020b4601017f200145044041000f0b024003402002200220002c000041bf7f4a6a22024b0d01200041016a2100200141016b22010d000b20020f0b41808904411c418499041011000b3e00200220034f044020002003360204200020013602002000410c6a200220036b3602002000200120034102746a3602080f0b41a49904412320041011000b39000240027f2002418080c40047044041012000200220012802101101000d011a0b20030d0141000b0f0b200020034100200128020c1100000bae0101027f20022104024002400240200320012d0020220320034103461b41ff0171220341016b0e03010001020b200241016a2203044020034101762104200241017621030c020b41808904411c41e08d041011000b41002104200221030b200341016a2102200128021c2103200128020421052001280200210102400340200241016b2202450d01200120032005280210110100450d000b418080c40021030b20002003360204200020043602000b3201017f027f0340200020002004460d011a200441016a2104200220012003280210110100450d000b200441016b0b2000490b4b01017f230041106b22052400200120034d0440200541086a4100200120021026200528020c21012000200528020836020020002001360204200541106a24000f0b200120032004102f000b7501017f230041306b220324002003200136020420032000360200200341146a41023602002003411c6a41023602002003412c6a410536020020034188900436021020034100360208200341053602242003200341206a3602182003200341046a36022820032003360220200341086a2002100b000bea04010b7f230041106b2209240020002802042104200028020021030240024002402001280208220b410147200128021022024101477145044020024101470d02200320046a210c200141146a28020041016a210a410021022003210003402000200c460d03027f024020002c0000220641004e0440200041016a2105200641ff017121070c010b20002d0001413f7121052006411f7121072006415f4d044020074106742005722107200041026a21050c010b20002d0002413f7120054106747221082006417049044020082007410c74722107200041036a21050c010b200041046a210520022106418080c4002007411274418080f0007120002d0003413f71200841067472722207418080c400460d011a0b2002200520006b6a22062002490d0320070b2108200a41016b220a044020052100200621022008418080c400470d010c040b0b2008418080c400460d02024002402002450d00200220044f04404100210020022004460d010c020b41002100200220036a2c00004140480d010b200321000b2002200420001b21042000200320001b21030c020b200128020020032004200128020428020c11000021000c020b41808904411c41b495041011000b200b450440200128020020032004200128020428020c11000021000c010b2001410c6a2802002200200320046a2003102822024b0440200941086a2001200020026b4100102c41012100200928020c2202418080c400460d0120092802082001280200220520032004200141046a280200220128020c1100000d01200220052001102d21000c010b200128020020032004200128020428020c11000021000b200941106a240020000b140020002802002001200028020428020c1101000b5501027f0240027f02400240200228020041016b0e020103000b200241046a0c010b200120022802044103746a22012802044106470d0120012802000b2802002104410121030b20002004360204200020033602000b4901017f230041206b22032400200341186a200241106a290200370300200341106a200241086a2902003703002003200229020037030820002001200341086a1019200341206a24000bda08010b7f23004190016b22032400200341003b0184012003410a3602800120034281808080a00137037820032002360274200341003602702003200236026c200320013602682003200236026420034100360260200028020421062000280200210720002802082108200341fc006a2109027f0340024002400240024020032d008501450440200341d8006a2003280268220c200328026c2003280270200328027410350240024020032802582201450d00200328025c2100034002400240024002400240027f0240024002400240200328027822020440200220096a41016b2d00002104200041084f04402001200141036a417c712202460440200041086b210a410021020c040b200341d0006a200220016b22022000200020024b1b22022001200041e48e04102e200341c8006a200420032802502003280254103620032802484101470d02200328024c21010c050b200341306a20042001200010362003280234210120032802300c050b41a08904412141cc97041011000b2002200041086b220a4b0d010b200441818284086c210b0340200241046a22052002490d04200120026a280200200b73220d417f73200d41818284086b71200120056a280200200b732205417f73200541818284086b7172418081828478710d012002200241086a22024b0d072002200a4d0d000b0b200341406b20012000200241948f041025200341386a2004200328024020032802441036410020032802384101470d011a2002200328023c6a220120024f0d0041808904411c41a48f041011000b41010b4101460440200141016a2200450d022000200328027022006a22022000490d0320032002360270200220032802782200490d05200341286a2003280268200328026c200220006b2002103520032802282202450d05200328022c2100200341206a20032802782009410441fc9704102e20022000200328022020032802241037450d05200341186a200328026020032802702200200c103820032000360260200328021c2102200328021821000c080b200320032802743602700c060b41808904411c41f48e041011000b41808904411c41dc97041011000b41808904411c41ec97041011000b41808904411c41848f041011000b200341106a2003280268200328026c20032802702003280274103520032802142100200328021022010d000b0b4100210020032d0085010d00024020032d008401044020032802642101200328026021040c010b2003280264220120032802602204490d0420012004460d010b200341013a008501200341086a2004200120032802681038200328020c2102200328020821000b20000d010b41000c050b20082d0000450d01200741a08a044104200628020c110000450d010c020b41a08904412141c495041011000b2003410a36028c0120082002047f200320002002200241016b419c920410252003418c016a41012003280200200328020410370541000b3a0000200720002002200628020c110000450d010b0b41010b20034190016a24000b4c01037f230041106b220524002002200449200320044b72450440200541086a2003200420011026200528020c2107200528020821060b2000200736020420002006360200200541106a24000b5701027f024002402003450440410021030c010b200141ff017121054101210103402005200220046a2d0000460440200421030c030b2003200441016a2204470d000b0b410021010b20002003360204200020013602000b4d01017f2001200346047f027f034041002001450d011a200141016b210120022d0000210320002d00002104200041016a2100200241016a210220032004460d000b200420036b0b0541010b450b1400200020012002200341c8960441a08904103f0b5801027f230041206b22022400200128020421032001280200200241186a2000280200220041106a290200370300200241106a200041086a290200370300200220002902003703082003200241086a1019200241206a24000b0b002000280200200110300b1800200128020041b4a0044105200128020428020c1100000b990301037f230041406a22022400200028020021034101210002402001280200220441ec8904410c200141046a280200220128020c1100000d0002402003280208220004402002200036020c200241346a4102360200410121002002413c6a4101360200200241fc890436023020024100360228200241073602142002200241106a36023820022002410c6a36021020042001200241286a1033450d010c020b20032802002200200328020428020c11090042c8b5e0cfca86dbd3897f520d002002200036020c200241346a4102360200410121002002413c6a4101360200200241fc890436023020024100360228200241083602142002200241106a36023820022002410c6a36021020042001200241286a10330d010b200328020c21002002411c6a4103360200200241246a41033602002002413c6a4105360200200241346a4105360200200241c489043602182002410036021020022000410c6a3602382002200041086a3602302002410236022c200220003602282002200241286a36022020042001200241106a103321000b200241406b240020000b980401047f230041106b22022400024002400240024002400240024002400240024002400240024020002d000041016b0e0b0102030405060708090a0b000b4101210020012802002203418a9d0441062001280204220528020c22041100000d0b024020012d0018410471450440200341a88a04410120041100000d0d200341b4a00441052004110000450d010c0d0b200341a68a04410220041100000d0c2002200536020420022003360200200241013a000f20022002410f6a360208200241b4a004410510340d0c200241a48a04410210340d0c0b200341c189044101200411000021000c0b0b200128020041fd9c04410d200128020428020c11000021000c0a0b200128020041ef9c04410e200128020428020c11000021000c090b200128020041e49c04410b200128020428020c11000021000c080b200128020041ca9c04411a200128020428020c11000021000c070b200128020041bc9c04410e200128020428020c11000021000c060b200128020041ac9c044110200128020428020c11000021000c050b200128020041a09c04410c200128020428020c11000021000c040b200128020041959c04410b200128020428020c11000021000c030b2001280200418e9c044107200128020428020c11000021000c020b200128020041ff9b04410f200128020428020c11000021000c010b200128020041ec9b044113200128020428020c11000021000b200241106a240020000b1400200020012002200341849f0441a09f04103f0b2800200120024d04402000200220016b3602042000200120036a3602000f0b2005412120041011000b0bf6200400418080040ba103636f756c64206e6f742070726f7065726c79206465636f64652073746f7261676520656e7472792f55736572732f7061726974792f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f696e6b5f73746f726167652d332e342e302f7372632f7472616974732f6d6f642e72732700010061000000a20000000a00000073746f7261676520656e7472792077617320656d707479002700010061000000a30000000a0000000900000001000000010000000a0000002f55736572732f7061726974792f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f696e6b5f656e762d332e342e302f7372632f656e67696e652f6f6e5f636861696e2f696d706c732e7273656e636f756e746572656420756e6578706563746564206572726f72380101001c000000d000010068000000f6000000170000002f55736572732f7061726974792f436f64652f3466756e2f666c69707065722f6c69622e727300006c0101002600000008000000050041c483040b716469737061746368696e6720696e6b2120636f6e7374727563746f72206661696c65643a20000000c4010100250000006469737061746368696e6720696e6b21206d657373616765206661696c65643a20000000f4010100210000000900000004000000040000000b0000000c0000000d0041c084040bd11a617474656d707420746f206164642077697468206f766572666c6f7700000000617474656d707420746f206d756c7469706c792077697468206f766572666c6f770000000900000000000000010000000e0000002f55736572732f7061726974792f2e7275737475702f746f6f6c636861696e732f6e696768746c792d616172636836342d6170706c652d64617277696e2f6c69622f727573746c69622f7372632f727573742f6c6962726172792f616c6c6f632f7372632f7261775f7665632e727300940201006f0000008a0100001c0000006361706163697479206f766572666c6f770000001403010011000000940201006f00000006020000050000006120666f726d617474696e6720747261697420696d706c656d656e746174696f6e2072657475726e656420616e206572726f722f55736572732f7061726974792f2e7275737475702f746f6f6c636861696e732f6e696768746c792d616172636836342d6170706c652d64617277696e2f6c69622f727573746c69622f7372632f727573742f6c6962726172792f616c6c6f632f7372632f666d742e72730000730301006b00000064020000200000002f55736572732f7061726974792f2e7275737475702f746f6f6c636861696e732f6e696768746c792d616172636836342d6170706c652d64617277696e2f6c69622f727573746c69622f7372632f727573742f6c6962726172792f616c6c6f632f7372632f7665632f6d6f642e727300f00301006f0000002f0700000d000000f00301006f0000009d07000009000000617474656d707420746f206164642077697468206f766572666c6f7700000000617474656d707420746f2073756274726163742077697468206f766572666c6f77293a00900e010000000000c204010001000000c2040100010000000900000000000000010000000f00000070616e69636b65642061742027272c20f804010001000000f9040100030000003a200000900e0100000000000c05010002000000202020202c0a280a282f55736572732f7061726974792f2e7275737475702f746f6f6c636861696e732f6e696768746c792d616172636836342d6170706c652d64617277696e2f6c69622f727573746c69622f7372632f727573742f6c6962726172792f636f72652f7372632f666d742f6e756d2e727330303031303230333034303530363037303830393130313131323133313431353136313731383139323032313232323332343235323632373238323933303331333233333334333533363337333833393430343134323433343434353436343734383439353035313532353335343535353635373538353936303631363236333634363536363637363836393730373137323733373437353736373737383739383038313832383338343835383638373838383939303931393239333934393539363937393839392f55736572732f7061726974792f2e7275737475702f746f6f6c636861696e732f6e696768746c792d616172636836342d6170706c652d64617277696e2f6c69622f727573746c69622f7372632f727573742f6c6962726172792f636f72652f7372632f666d742f6d6f642e72730000005f0601006e0000005d0500000d0000005f0601006e000000ed050000380000002f55736572732f7061726974792f2e7275737475702f746f6f6c636861696e732f6e696768746c792d616172636836342d6170706c652d64617277696e2f6c69622f727573746c69622f7372632f727573742f6c6962726172792f636f72652f7372632f736c6963652f6d656d6368722e727300f0060100730000004e0000002f000000f0060100730000005a0000001f000000f0060100730000006300000009000000f0060100730000006800000027000000f006010073000000680000003e00000072616e676520737461727420696e64657820206f7574206f662072616e676520666f7220736c696365206f66206c656e67746820b407010012000000c60701002200000072616e676520656e6420696e64657820f807010010000000c6070100220000002f55736572732f7061726974792f2e7275737475702f746f6f6c636861696e732f6e696768746c792d616172636836342d6170706c652d64617277696e2f6c69622f727573746c69622f7372632f727573742f6c6962726172792f636f72652f7372632f736c6963652f697465722e72730000001808010071000000c4050000250000002f55736572732f7061726974792f2e7275737475702f746f6f6c636861696e732f6e696768746c792d616172636836342d6170706c652d64617277696e2f6c69622f727573746c69622f7372632f727573742f6c6962726172792f636f72652f7372632f736c6963652f6d6f642e72739c08010070000000f30300002f0000009c08010070000000d30800001e000000736f7572636520736c696365206c656e67746820282920646f6573206e6f74206d617463682064657374696e6174696f6e20736c696365206c656e67746820282c09010015000000410901002b000000c1040100010000002f55736572732f7061726974792f2e7275737475702f746f6f6c636861696e732f6e696768746c792d616172636836342d6170706c652d64617277696e2f6c69622f727573746c69622f7372632f727573742f6c6962726172792f636f72652f7372632f7374722f636f756e742e7273840901007000000047000000150000008409010070000000540000001100000084090100700000005a00000009000000840901007000000064000000110000008409010070000000660000000d0000002f55736572732f7061726974792f2e7275737475702f746f6f6c636861696e732f6e696768746c792d616172636836342d6170706c652d64617277696e2f6c69622f727573746c69622f7372632f727573742f6c6962726172792f636f72652f7372632f7374722f697465722e727300440a01006f0000009100000011000000440a01006f0000004c0200003c0000002f55736572732f7061726974792f2e7275737475702f746f6f6c636861696e732f6e696768746c792d616172636836342d6170706c652d64617277696e2f6c69622f727573746c69622f7372632f727573742f6c6962726172792f636f72652f7372632f7374722f7472616974732e7273000000d40a010071000000ca000000130000002f55736572732f7061726974792f2e7275737475702f746f6f6c636861696e732f6e696768746c792d616172636836342d6170706c652d64617277696e2f6c69622f727573746c69622f7372632f727573742f6c6962726172792f636f72652f7372632f7374722f7061747465726e2e72730000580b010072000000a101000047000000580b010072000000b401000020000000580b010072000000b401000011000000580b010072000000b8010000260000002f55736572732f7061726974792f2e7275737475702f746f6f6c636861696e732f6e696768746c792d616172636836342d6170706c652d64617277696e2f6c69622f727573746c69622f7372632f727573742f6c6962726172792f636f72652f7372632f697465722f7472616974732f616363756d2e72730c0c0100780000008d00000001000000290501006e000000cd01000005000000617373657274696f6e206661696c65643a206d6964203c3d2073656c662e6c656e28290a900e010000000000c70c0100010000002f55736572732f7061726974792f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f696e6b5f656e762d332e342e302f7372632f656e67696e652f6f6e5f636861696e2f6275666665722e7273000000d80c0100690000005800000009000000d80c0100690000005800000031000000d80c0100690000008b000000210000002f55736572732f7061726974792f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f696e6b5f656e762d332e342e302f7372632f656e67696e652f6f6e5f636861696e2f6578742e72730000740d0100660000008c0100001400000045636473615265636f766572794661696c65644c6f6767696e6744697361626c6564556e6b6e6f776e4e6f7443616c6c61626c65436f64654e6f74466f756e645f456e646f776d656e74546f6f4c6f775472616e736665724661696c65645f42656c6f7753756273697374656e63655468726573686f6c644b65794e6f74466f756e6443616c6c6565526576657274656443616c6c6565547261707065644465636f6465900e0100000000007061696420616e20756e70617961626c65206d657373616765636f756c64206e6f74207265616420696e707574756e61626c6520746f206465636f646520696e707574656e636f756e746572656420756e6b6e6f776e2073656c6563746f72756e61626c6520746f206465636f64652073656c6563746f722f55736572732f7061726974792f2e7275737475702f746f6f6c636861696e732f6e696768746c792d616172636836342d6170706c652d64617277696e2f6c69622f727573746c69622f7372632f727573742f6c6962726172792f636f72652f7372632f736c6963652f696e6465782e72730000100f01007200000081010000470041a09f040bf301617474656d707420746f2073756274726163742077697468206f766572666c6f772f55736572732f7061726974792f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f7061726974792d7363616c652d636f6465632d332e322e312f7372632f636f6465632e7273c10f0100630000007a0000000e0000004572726f72000000000000000100000002000000030000000400000005000000060000000700000008000000090000000c0000000b000000190000001c000000160000001400000019000000f70e0100db0e0100c50e0100b10e0100980e01"},"contract":{"name":"flipper","version":"0.1.0","authors":["[your_name] <[your_email]>"]},"V3":{"spec":{"constructors":[{"args":[{"label":"init_value","type":{"displayName":["bool"],"type":0}}],"docs":["Constructor that initializes the `bool` value to the given `init_value`."],"label":"new","payable":false,"selector":"0x9bae9d5e"},{"args":[],"docs":["Constructor that initializes the `bool` value to `false`.","","Constructors can delegate to other constructors."],"label":"default","payable":false,"selector":"0xed4b9d1b"}],"docs":[],"events":[],"messages":[{"args":[],"docs":[" A message that can be called on instantiated contracts."," This one flips the value of the stored `bool` from `true`"," to `false` and vice versa."],"label":"flip","mutates":true,"payable":false,"returnType":null,"selector":"0x633aa551"},{"args":[],"docs":[" Simply returns the current value of our `bool`."],"label":"get","mutates":false,"payable":false,"returnType":{"displayName":["bool"],"type":0},"selector":"0x2f865bd9"}]},"storage":{"struct":{"fields":[{"layout":{"cell":{"key":"0x0000000000000000000000000000000000000000000000000000000000000000","ty":0}},"name":"value"}]}},"types":[{"id":0,"type":{"def":{"primitive":"bool"}}}]}} \ No newline at end of file diff --git a/examples/smart_contract/flipper.wasm b/examples/smart_contract/flipper.wasm new file mode 100644 index 0000000000000000000000000000000000000000..fa0674ef762a74dcc1a410cb5436d33628ef7de7 GIT binary patch literal 15044 zcmchedyHJyUB}OT%wzY?*texOoZiS4>c+EP-85XheFj_rMT zXFW6P2ZFBCx}i-2q!4IA8|u(ND?t&UAn^x+6a}ctD~L)ITA@hv4}=0lwBjKZh0ph# zJL6p^5X!?|-MQy=f9LmpoO^AW-E)C4CU{r%RJ6Id8El>k`@iN?fsxHk<7UjM*mnX3 zOx|O8uo=8xKbxlvSJ6GOX~Itjr9!vWTy5N<-;;~2`!>#;JlE=Wn`c@k@KdRq>b80( zyS;Wt6Y8 zEt)WDtz9UdYn^L%E{8#wMsGcA!k`$0!%RhS5|)ak2zJClV2Y)%7z{;)APAyzp&T(5 z8xs}E8VQ0zB`yT(L7Em=T84gmTkEUs%Vt-+&|F#f6o`rU`$5(JykW)^1Av3N5xh0J8pau)D&(3r!9o(-03Q6)%{ zcMVz(KMoOPhK!$K!9EyBZ#OqFXgW-}Kk~siO-%AJ1SeV=o|bR` zDYW}?n4xtrQ}6(a7!^*3w?e2vCN}KVjeY)FybOuc;Q%bcEH9@M+#1lCT#YE*j)YLMyPY|>DP02v zr+r#0y$l_l&wQO+S?Jy$1BjN7U*rDUqs1hgk>8r8b zXRkiy6f4aj;^_xsD>jcT+p8an?Q=gGr>|oenBp-lVEUFx=Dl8^<6hUWzMZftaQd58 z<4qeDP-N8opxKEE1jqJTWVtsHgCxdNL7W?jq$ne)qy8uA1(0_lVmYi3mx}4z;3lja zLB05?*e96mo8bIE&D;=<0j+CQ~=a3#yQc^8hG^{pu&=DdGM8 zsEnZd(s?!t3b})F7=rM8IG^5PUkuLMf|Cew1}YD*rSstMPS)}oVYxpVnTg5{UtG)% z=d!R;Gh%`|zVHJ0qOKRfm(Xwl``)AhWF|im97o)N{rliJu0Xr}p*h}xgK9n=9Pd

l%C{q6yogj_EwkJ24BFihh^c!U^WHcAwFonGe} z-j5Bq{ts@~W-kdA%fs&$=bbhKuOD(I272H;i&Ov*6|V{kYAN(8G*qNi-kCgD^jh$& zaf&Kl`9IG+#I;owZfAR^3bQn32dXgZRKdk_k+%bW6T%ueZ}eg8W%Ysmy*7+`W%wJ@ zSBAp_UHAp*0>Z2XNbAqcaRe9jwc&w*Hhe{DfX%yAe;FLBhVZo(R6@mk{LyuugY!VJ zm}_6`19>`OXU69*1Y0TpWS`;&4L2gv;W=!e0S`i%rlWl%oK0Wtxd+0PcSAoxsAqr6 z2k{+oXiT6~#6Dy46u{U&qUk)0v0wTC;(~SF)x3iS6Q0xds~>QV3Xd`f9IumX1N-Rx zJXPN6YWm)5t6t^Vivx*REx2&rJa%`G?%! zL!A$D5uC^(SjE41CTbuyb{g@wj7SFg{RroSgHOEzg@5I zlh$B;Er{l`Ad_xrjLdnN)h-*X7o|2NRo*of)!v6&dX+I%T(guCEsBA!pSV_ZDI+z2 zqHI=tRbY;iI?BQU9M?;>(5soOBpluj3hc`QoQ8Id5$27%76f_QuJ{$jjeWivf-Q7* zc~*-rN)#chj!MXljx$f%l+Hx331pF{(((RyS@n;STreiStbm*HamWY|1(X%CB5VUO z;o)ea75B*^ky4_ixze3|Mmbta?x{g!-^w;DPbnDH9{^n~wG-tR4ET_eK_>U2Re4^h ziE=$!5p)n>!MCSxaDz1%p|IhL!;o}L)AZ^Ai}TF)g%9^jDm0{={B{_G*Q++~|3Uz> zd0pmLS-sRN{imLGFl?y!EkOMR)Q{W24tDLY@E~rvU`yxi3m!_Gq=R6hf1Ov6nEd>b88RTAN+_24!ssOB$$(N?9&$%vFkL z2wqU^jGTw_#Y3&=eX*Qp(D^JRXHbrr_5e~s0e|>BryUNGAhlvXHGA~|XRUh;QZRnGQZ9K&lk7}V>epif4fJ7jTeucJ zJowoM@^I}k2|Tw1?{h2rt878h^F)9nkjnMt14G2sh_Zf9INujdxJ5MBpOg?mT&Rc0 zD3XlG@+G54*&iKbgywO}VUhCW5^~CofZY~hE*&vB(?J$KPpO%>)h|7h$OOp_$bnIN zqWOve>xwz@OaJsIAN<_c|K+dlNPa!=tRTsf77K7Zk5+Sv<5=T(4$Qm?g;8$1m#;_v z_9t?d<(ztHJxb8XOHySE$}4>a;MHHAH%Q+s1F6&kcBN7FqIWcT^+4_XSY_Ufl% zd+j4}`u60@#W3*|XddsKI}SfrtKt>5{lVIY|HR;z?QJ!aRcmDL(LA_dRpS2ZDMR6~ zjaRZA*^VPDy;860_WmFF42L+9l>M4ns~2t1vmgIxygX{mTa8>;xFX|Va&^To+rEGu z6d89MdGYgqG5WpQn3$ebKf_*sWA1jP84hX)YpIkIhnpsFVt^h#QFV4^*rbj$z;f9= z%G>~>@ITvHt{4b#)P^MKm4Z_8Er7!9q{v>e7KIy55C_}oPz^_~(cA8%Oc}|{ijvBe zI&q%dhO~onx3sqwS{+}Kgq(-RSPva{@~3vnffU^3`NX~jH}niKe=kW?&i7h5oEI>; zL>s^@#8>=M|7xwXdc$tDyvs zW2UTD@z8aClle`2N~7(D^G&2+$~m*4ELi0|1SbFNb+g(H2$ANYMH4u-FvzsZ&|lc5)QC>>vl=h3qL;qw|ZC(w@gP90<7 ziB_-|tcul~d+$e0Xf4-CQCW@Q+vt3{U(T$kB#ASS3$=p4M@a5ymHGqBRW3YDxaQ}? zUi;9;;`BSj_6jLDw{lGfP&6D9VpP=t+CKD?gJna0SqY?B#tJExah02Uj%bJ}^pI2?Im;5Kn6G|7dgw(8K@BhHnGEp>e2Yz@qvi(#wdzke3dG!&W zIL6tq&VH4QiCyIj_Qm_ZS%PE!zD$&gR|yH;GO{6M``Hk9am?(|5*8(iIL=Xsx1n$+ z>Q({;EJ<#rZUo?!H@lmYColP@Jf?Z?k!`&vxAng9Q=TSFFx_8MX!k)obWt@^v80sG z@lF_+1IF0j*?ebC8!lzJh91bX1P;rA_T>l6ZBz07u<3HKBXX$gfF}Zg+sxw%(On`RY2-r$) za5@OJ7I`m+w!cqlCimO!m3?a^%WSr0)Zbsr0$(arhF(S4A6>;bK^BP`( z+7rp0+oC;-q`OKz#RdfWO0jqAQTB$1MW*1&YoB&RD&ED`ex?u&POhWD$#rBu{IJUu z;J$Jy4pek z-=K4VqCF{YmTa+?6*|rmL!QakhOC9t#a;)WRkZ7hPh}QY7?9CM{iU*Ed^DN8kB;`1 z9<3M5dF>bpN?A}kWcfY-NTU^W%*rw@mJ}k&N(q|`OPz)#-x~f40?Y0Jd8imylM z$1~JURuU^MGOVYmb7Pd*_o8K)@%%f8+hUYedFgED{8-V5zn;_tv5$fiVP|*W4V5XcV zd%3d~R2)XR=qItfEDCbGt_m?O(G-?}Q!~K`O!7YE{CF78Hl|_ojxdPC6Si}3-7$?j zyAUI65uUrv5|$HM0&mNhfMcI*`GhwnU&o^El*7c={@ItyLqh1!&%#KQ^Rq7@C*$DQ zOUA>o*I$*rfjo@#{kfNUYj9PohNr_T+>hK(1$B*g)|cQB*?f;F%y8ZJR=MGB&-&h? zpF8F4i~ueIP}e;4+HacW+K_yZxZyYw9W)q#CZfKrR|4pzLy=aDesGTpQ5b=5_BtBq5Z;;efx zm&p2*t?`~lP|+L-n}sU`lqvNvV3*I0ga@!$>8VC9VQ8`aCX73z)f&q5b89-|R?7zH zp3)C{XO&dPlxV6O*(Z-p)j?LxQ4<)USD;iW_QUTtkg%xn!T76QK6&r?ZN00WZV)5e z2To3bwsl}V5xa!C;z=NuJGba`y=ubwjMmivma$;b>&B^?UU<0yxXk#eI;pT^FUKm8 zQF?qxW~myOVV0Z~g}50{T3K$EgoVANgJtwyxk1TZdyuqR$3OCE49QFTjQyG1!8%)i zC?LRueEb5_U~q`(*iVufOFJG4uq5r}Xo}Mr4({EnIc%G?*I`4cL-yf7zU8jL=PLfN zAU*+b(tY`JcYx)bZa<4Cx%$1vXA2a0-q#hC9OPyE_jyMO(_G5vzQsZ36kw?&T{5m( zCDswO)R9kPbRfnS(#zN-)QAD}AmVzSnB0vk6+ijzN1n;zB4N@Vsq+f52?3|K%DTyo z5Z7fl++1pKOgSkYVI={H+MYUyK`)M;<17v&RP8J%9$y=F;Chs=>L{Kj*C`o#yn^5-Afe6PzhzQwIM1bU^d zolVJhL;Rw!K&xk}FCW8-OB_ShGB-$h`Pd$$AfCd~BSgNoZy++0JQ@$aRY5cgUoZdX)K7^+5`Wtw7otl&e0-nSu|} zI{|%5rbImS0Mbb zT=O~_xED9|<4l#dKb2><_Qg-ccIWmfJdk_pd8YWzV9Q=g3Af~u8Quq0xCke- zXvm!(Fw_5958s6}sG;$cHDA;w|D45yX}*GdB3fu~tS)A2?OwLtX|K0BtCzFI)Rlc^w9xFFX^(bVXO_B}>~Tx^y3qjalXSH?zLXRp4`n55~#)#ij0gv$t?|Y3)n~J8RiOdkx-iEbu*U zcDlK=+FCrEvHlsJeG~VWtk1vb-MaQ0tgW$DJdE=z;a=e)kK;qV$S7y z;$n6YF=y=ytG85K?EO+uK+l?X}yhj>+B8 zwWTv>d#jfZHk+M=v(u9Yo9pYVt%Hlr&P7B3n@07B?$SK9HP~sQihRl2Uhu=sizhF% z7R1p2I|%>@*BD4NtPcrJo(#{H&j4qtP-H7~Hgcsp8>(wIU2ar%<` z7X5f7{poJp2ZI-S+x2JvVe{|~X^t_!8wXB@`uDARwUhbv=GxN2iX_p?ZoBP3_OJQ+ zf8!o8FAM3zs_;2DEHfGZ4h)YBkNiI}ZlT?2Ih{mkqiY-I5L~0t7;B6-CK{8Csm63; zrZL-?8*7Y>jg5~@j7^SBjZKfujLnYCjW@=}#>dAe#wW+8#;3<;#%IUpCK?lC6XO#T z6O$8D6Vnqj6SEU@la0x-$??gF$;rv7$?3_N$=S)dsm9dU)cDlI)a2CE)b!NM)a=yU zbYpsKdVG3fdUASddU|?hdUkqlrZF=%Gd?phGdVLgGd(jiGdnXk+n61j9iN?;ot&MT zot~YUot>SV1I0PEp9Az9kIgZ3v$*D?1oApr49pt$AH+DNZ~gw?)1Re(GZ5;oE-kc1 z`QHf(XFD>&7r+U>ZQiB*x%&O@r~QU4{RP_6+5WtO!)-V8-$tMR2ysRMxY_C9>=#>? zvaG$)%i5J}nU?ovSjt z%Yiu$4$mN~H*vptIC%B>B>S(k@7Hk#l2gC`=S13Xr{8UFbQWN|#M|fV$o_1x-Rim& zi7>Emmi(woFz~*A`_cnLfq4yZEcdr?|9tL$ZVH{f&ZtXCVD(k@7oEqsgipVJ4{gP` zeqZ`2eeCxaZ2UlR4U8)P0OZ79^b4!ca?cbSoTdSuJ;owI05BKBt9{@`*ZlL9V zP?7xCiT-^Xr}@8VUiM#R&n5P}mrM4twLi9{|54gCuK#b`T9gzhn_nZ=Vw z*B09smD%3YZr|0ucu)R6@;s=MM_T0k-?MRFm#UBYr*+TSPOE#iy}Ed3>vA82z_wcN zZGi#xknaJ8`eyMCS6BAsxZXs>WXv0D>&?qTB+Dz5>lJCI)l~H2zYuP$xfRqPd2#AS zx7T2fFlh{xSiAF*C;AgN$majD_86pjK0k1g+bK}G)7$O+$mzJT*FF^|Uk|n<#xI}v z-hk=1sNud;KiK8}Hnt9`pkJV>9X~YY@=(_Ywa" + ] + }, + "V3": { + "spec": { + "constructors": [ + { + "args": [ + { + "label": "init_value", + "type": { + "displayName": [ + "bool" + ], + "type": 0 + } + } + ], + "docs": [ + "Constructor that initializes the `bool` value to the given `init_value`." + ], + "label": "new", + "payable": false, + "selector": "0x9bae9d5e" + }, + { + "args": [], + "docs": [ + "Constructor that initializes the `bool` value to `false`.", + "", + "Constructors can delegate to other constructors." + ], + "label": "default", + "payable": false, + "selector": "0xed4b9d1b" + } + ], + "docs": [], + "events": [], + "messages": [ + { + "args": [], + "docs": [ + " A message that can be called on instantiated contracts.", + " This one flips the value of the stored `bool` from `true`", + " to `false` and vice versa." + ], + "label": "flip", + "mutates": true, + "payable": false, + "returnType": null, + "selector": "0x633aa551" + }, + { + "args": [], + "docs": [ + " Simply returns the current value of our `bool`." + ], + "label": "get", + "mutates": false, + "payable": false, + "returnType": { + "displayName": [ + "bool" + ], + "type": 0 + }, + "selector": "0x2f865bd9" + } + ] + }, + "storage": { + "struct": { + "fields": [ + { + "layout": { + "cell": { + "key": "0x0000000000000000000000000000000000000000000000000000000000000000", + "ty": 0 + } + }, + "name": "value" + } + ] + } + }, + "types": [ + { + "id": 0, + "type": { + "def": { + "primitive": "bool" + } + } + } + ] + } +} \ No newline at end of file From 98cbf1fd73bb4d4098daa6082918bc328a593288 Mon Sep 17 00:00:00 2001 From: Matias Volpe Date: Mon, 12 Dec 2022 12:26:29 -0300 Subject: [PATCH 02/21] feat: use zombienet in smart contract example --- effects/rpc_known_clients.ts | 1 - examples/smart_contract.toml | 24 ++++++++++++++++++++++++ examples/smart_contract.ts | 26 ++++++++++++++++++++------ 3 files changed, 44 insertions(+), 7 deletions(-) create mode 100644 examples/smart_contract.toml diff --git a/effects/rpc_known_clients.ts b/effects/rpc_known_clients.ts index 8ffd8bb41..166565742 100644 --- a/effects/rpc_known_clients.ts +++ b/effects/rpc_known_clients.ts @@ -14,4 +14,3 @@ export const moonbeam = proxyClient("wss://wss.api.moonbeam.network") export const statemint = proxyClient("wss://statemint-rpc.polkadot.io") export const subsocial = proxyClient("wss://para.subsocial.network") export const westend = proxyClient("wss://westend-rpc.polkadot.io") -export const local = proxyClient("ws://127.0.0.1:9944") diff --git a/examples/smart_contract.toml b/examples/smart_contract.toml new file mode 100644 index 000000000..412088413 --- /dev/null +++ b/examples/smart_contract.toml @@ -0,0 +1,24 @@ +[relaychain] +default_image = "docker.io/paritypr/polkadot-debug:master" +default_command = "polkadot" +default_args = ["-lparachain=debug"] +chain = "rococo-local" + +[[relaychain.nodes]] +name = "alice" +validator = true + +[[relaychain.nodes]] +name = "bob" +validator = true + +[[parachains]] +id = 1000 +cumulus_based = true +chain = "contracts-rococo-local" + +[parachains.collator] +name = "collator01" +image = "docker.io/parity/polkadot-parachain:latest" +command = "polkadot-parachain" +args = ["-lparachain=debug"] diff --git a/examples/smart_contract.ts b/examples/smart_contract.ts index d2d789823..391714aad 100644 --- a/examples/smart_contract.ts +++ b/examples/smart_contract.ts @@ -1,12 +1,17 @@ +import * as path from "http://localhost:5646/@local/deps/std/path.ts" import * as C from "http://localhost:5646/@local/mod.ts" import * as T from "http://localhost:5646/@local/test_util/mod.ts" import * as U from "http://localhost:5646/@local/util/mod.ts" import { $contractsApiCallArgs, $contractsApiCallReturn } from "./smart_contract/codec.ts" +const configFile = getFilePath("smart_contract.toml") +const zombienet = await T.zombienet.start(configFile) +const client = zombienet.clients.byName["collator01"]! + const contract = await getContract( - "./examples/smart_contract/flipper.wasm", - "./examples/smart_contract/metadata.json", + getFilePath("smart_contract/flipper.wasm"), + getFilePath("smart_contract/metadata.json"), ) const contractAddress = U.throwIfError(await instantiateContractTx().run()) @@ -15,9 +20,11 @@ console.log("get message", U.throwIfError(await sendGetMessage(contractAddress). console.log("flip message in block", U.throwIfError(await sendFlipMessage(contractAddress).run())) console.log("get message", U.throwIfError(await sendGetMessage(contractAddress).run())) +await zombienet.close() + function instantiateContractTx() { const constructor = findContractConstructorByLabel("default")! - const tx = C.extrinsic(C.local)({ + const tx = C.extrinsic(client)({ sender: T.alice.address, call: { type: "Contracts", @@ -68,7 +75,7 @@ function sendMessageDryRunContractCall( undefined, U.hex.decode(message.selector), ])) - return C.state.call(C.local)( + return C.state.call(client)( "ContractsApi_call", key, ) @@ -87,7 +94,7 @@ function sendGetMessage(address: Uint8Array) { undefined, U.hex.decode(message.selector), ])) - return C.state.call(C.local)( + return C.state.call(client)( "ContractsApi_call", key, ) @@ -116,7 +123,7 @@ function sendFlipMessage(address: Uint8Array) { storageDepositLimit: undefined, } }) - return C.extrinsic(C.local)({ + return C.extrinsic(client)({ sender: T.alice.address, call: C.Z.rec({ type: "Contracts", @@ -157,3 +164,10 @@ async function getContract(wasmFile: string, metadataFile: string) { deriveCodec, } } + +function getFilePath(relativeFilePath: string) { + return path.join( + path.dirname(path.fromFileUrl(import.meta.url)), + relativeFilePath, + ) +} From 339c50935e8d7e11d51ca46b4a81b2258345caa1 Mon Sep 17 00:00:00 2001 From: Matias Volpe Date: Mon, 12 Dec 2022 12:33:39 -0300 Subject: [PATCH 03/21] fix: cspell and format --- cspell.json | 3 ++- examples/smart_contract/metadata.json | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/cspell.json b/cspell.json index 856043707..282c91603 100644 --- a/cspell.json +++ b/cspell.json @@ -17,6 +17,7 @@ "frame_metadata/raw_erc20_metadata.json", "target", "**/__snapshots__/*.snap", - "codegen/_output" + "codegen/_output", + "examples/smart_contract" ] } diff --git a/examples/smart_contract/metadata.json b/examples/smart_contract/metadata.json index cc9c0bfae..7060a8834 100644 --- a/examples/smart_contract/metadata.json +++ b/examples/smart_contract/metadata.json @@ -105,4 +105,4 @@ } ] } -} \ No newline at end of file +} From 7edfc6384c81fbc2c21cf79571e12134cb2ed340 Mon Sep 17 00:00:00 2001 From: Matias Volpe Date: Tue, 13 Dec 2022 10:36:08 -0300 Subject: [PATCH 04/21] feat: move ContractsApi_Call codec to frame_metadata --- examples/smart_contract.ts | 17 ++-- .../zombienet.toml} | 0 frame_metadata/Contract.ts | 77 +++++++++++++++++++ 3 files changed, 83 insertions(+), 11 deletions(-) rename examples/{smart_contract.toml => smart_contract/zombienet.toml} (100%) diff --git a/examples/smart_contract.ts b/examples/smart_contract.ts index 391714aad..4e26670a5 100644 --- a/examples/smart_contract.ts +++ b/examples/smart_contract.ts @@ -2,10 +2,9 @@ import * as path from "http://localhost:5646/@local/deps/std/path.ts" import * as C from "http://localhost:5646/@local/mod.ts" import * as T from "http://localhost:5646/@local/test_util/mod.ts" import * as U from "http://localhost:5646/@local/util/mod.ts" +import { $contractsApiCallArgs, $contractsApiCallReturn } from "../frame_metadata/Contract.ts" -import { $contractsApiCallArgs, $contractsApiCallReturn } from "./smart_contract/codec.ts" - -const configFile = getFilePath("smart_contract.toml") +const configFile = getFilePath("smart_contract/zombienet.toml") const zombienet = await T.zombienet.start(configFile) const client = zombienet.clients.byName["collator01"]! @@ -110,15 +109,15 @@ function sendGetMessage(address: Uint8Array) { function sendFlipMessage(address: Uint8Array) { const message = findContractMessageByLabel("flip")! const value = sendMessageDryRunContractCall(address, message) - .next(({ gas_required }) => { + .next(({ gasRequired }) => { return { type: "call", dest: C.MultiAddress.Id(address), value: 0n, data: U.hex.decode(message.selector), gasLimit: { - refTime: gas_required.ref_time, - proofSize: gas_required.proof_size, + refTime: gasRequired.refTime, + proofSize: gasRequired.proofSize, }, storageDepositLimit: undefined, } @@ -158,11 +157,7 @@ async function getContract(wasmFile: string, metadataFile: string) { await Deno.readTextFile(metadataFile), )) const deriveCodec = C.M.DeriveCodec(metadata.V3.types) - return { - wasm, - metadata, - deriveCodec, - } + return { wasm, metadata, deriveCodec } } function getFilePath(relativeFilePath: string) { diff --git a/examples/smart_contract.toml b/examples/smart_contract/zombienet.toml similarity index 100% rename from examples/smart_contract.toml rename to examples/smart_contract/zombienet.toml diff --git a/frame_metadata/Contract.ts b/frame_metadata/Contract.ts index fa33bbde1..524dbdf6a 100644 --- a/frame_metadata/Contract.ts +++ b/frame_metadata/Contract.ts @@ -1,3 +1,4 @@ +import * as $ from "../deps/scale.ts" import { unreachable } from "../deps/std/testing/asserts.ts" import { Ty, TyDef, UnionTyDefMember } from "./scale_info.ts" @@ -182,3 +183,79 @@ export namespace ContractMetadata { return normalize(contractMetadata).V3.types } } + +const $balanceCodec = $.u128 + +export interface Weight { + refTime: bigint + proofSize: bigint +} +const $weightCodec: $.Codec = $.object( + ["refTime", $.compact($.u64)], + ["proofSize", $.compact($.u64)], +) + +export type ContractsApiCallArgs = [ + origin: Uint8Array, + dest: Uint8Array, + balance: bigint, + weight: Weight | undefined, + storageDepositLimit: bigint | undefined, + data: Uint8Array, +] +export const $contractsApiCallArgs: $.Codec = $.tuple( + // origin + $.sizedUint8Array(32), + // dest + $.sizedUint8Array(32), + // balance + $balanceCodec, + // weight + $.option($weightCodec), + // storage_deposit_limit + $.option($balanceCodec), + // data + $.uint8Array, +) + +export interface ContractsApiCallReturn { + gasConsumed: Weight + gasRequired: Weight + storageDeposit: { + type: "Refund" + value: bigint + } | { + type: "Charge" + value: bigint + } + debugMessage: string + result: { + flags: number + data: Uint8Array + } +} +export const $contractsApiCallReturn: $.Codec = $.object( + // gas_consumed + ["gasConsumed", $weightCodec], + // gas_required + ["gasRequired", $weightCodec], + // storage_deposit + [ + "storageDeposit", + $.taggedUnion("type", [ + ["Refund", ["value", $balanceCodec]], + ["Charge", ["value", $balanceCodec]], + ]), + ], + // debug_message + ["debugMessage", $.str], + // result + [ + "result", + $.object( + ["flags", $.u32], + // TODO: improve result error coded + ["data", $.result($.uint8Array, $.never)], + ), + ], +) From 20adf7d18a74f5e3df8ee25261857af121a140e6 Mon Sep 17 00:00:00 2001 From: Matias Volpe Date: Wed, 14 Dec 2022 11:47:40 -0300 Subject: [PATCH 05/21] feat: compute gas estimate for contract instantiate --- examples/smart_contract.ts | 103 ++++++++++++++++++++++++++----------- frame_metadata/Contract.ts | 89 +++++++++++++++++++++++++++++++- 2 files changed, 161 insertions(+), 31 deletions(-) diff --git a/examples/smart_contract.ts b/examples/smart_contract.ts index 4e26670a5..33c1f142c 100644 --- a/examples/smart_contract.ts +++ b/examples/smart_contract.ts @@ -2,7 +2,12 @@ import * as path from "http://localhost:5646/@local/deps/std/path.ts" import * as C from "http://localhost:5646/@local/mod.ts" import * as T from "http://localhost:5646/@local/test_util/mod.ts" import * as U from "http://localhost:5646/@local/util/mod.ts" -import { $contractsApiCallArgs, $contractsApiCallReturn } from "../frame_metadata/Contract.ts" +import { + $contractsApiCallArgs, + $contractsApiCallResult, + $contractsApiInstantiateArgs, + $contractsApiInstantiateResult, +} from "../frame_metadata/Contract.ts" const configFile = getFilePath("smart_contract/zombienet.toml") const zombienet = await T.zombienet.start(configFile) @@ -23,31 +28,34 @@ await zombienet.close() function instantiateContractTx() { const constructor = findContractConstructorByLabel("default")! - const tx = C.extrinsic(client)({ - sender: T.alice.address, - call: { - type: "Contracts", - value: { + const salt = Uint8Array.from(Array.from([0, 0, 0, 0]), () => Math.floor(Math.random() * 16)) + const value = preSubmitContractInstantiateDryRunGasEstimate(constructor, contract.wasm, salt) + .next(({ gasRequired }) => { + return { type: "instantiateWithCode", value: 0n, - // TODO: create sendDryRunContractInitiate and fetch these gasLimit value gasLimit: { - refTime: 200_000_000_000n, - proofSize: 0n, + refTime: gasRequired.refTime, + proofSize: gasRequired.proofSize, }, storageDepositLimit: undefined, code: contract.wasm, data: U.hex.decode(constructor.selector), - salt: Uint8Array.from(Array.from([0, 0, 0, 0]), () => Math.floor(Math.random() * 16)), - }, - }, + salt, + } + }) + const tx = C.extrinsic(client)({ + sender: T.alice.address, + call: C.Z.rec({ + type: "Contracts", + value, + }), }) .signed(T.alice.sign) const finalizedIn = tx.watch(({ end }) => (status) => { - // .watch emits a single inBlock event - if (typeof status !== "string" && status.inBlock) { - return end(status.inBlock) + if (typeof status !== "string" && (status.inBlock ?? status.finalized)) { + return end(status.inBlock ?? status.finalized) } else if (C.rpc.known.TransactionStatus.isTerminal(status)) { return end(new Error()) } @@ -55,6 +63,12 @@ function instantiateContractTx() { } ) return C.events(tx, finalizedIn).next((events) => { + const extrinsicFailed = events.some((e) => + e.event?.type === "System" && e.event?.value?.type === "ExtrinsicFailed" + ) + if (extrinsicFailed) { + return new Error("extrinsic failed") + } const event = events.find((e) => e.event?.type === "Contracts" && e.event?.value?.type === "Instantiated" ) @@ -62,7 +76,30 @@ function instantiateContractTx() { }) } -function sendMessageDryRunContractCall( +function preSubmitContractInstantiateDryRunGasEstimate( + message: C.M.ContractMetadata.Constructor, + code: Uint8Array, + salt: Uint8Array, +) { + const key = U.hex.encode($contractsApiInstantiateArgs.encode([ + T.alice.publicKey, + 0n, + undefined, + undefined, + { type: "Upload", value: code }, + U.hex.decode(message.selector), + salt, + ])) + return C.state.call(client)( + "ContractsApi_instantiate", + key, + ) + .next((encodedResponse) => { + return $contractsApiInstantiateResult.decode(U.hex.decode(encodedResponse)) + }) +} + +function preSubmitContractCallDryRunGasEstimate( address: Uint8Array, message: C.M.ContractMetadata.Message | C.M.ContractMetadata.Constructor, ) { @@ -79,7 +116,7 @@ function sendMessageDryRunContractCall( key, ) .next((encodedResponse) => { - return $contractsApiCallReturn.decode(U.hex.decode(encodedResponse)) + return $contractsApiCallResult.decode(U.hex.decode(encodedResponse)) }) } @@ -98,7 +135,7 @@ function sendGetMessage(address: Uint8Array) { key, ) .next((encodedResponse) => { - const response = $contractsApiCallReturn.decode(U.hex.decode(encodedResponse)) + const response = $contractsApiCallResult.decode(U.hex.decode(encodedResponse)) if (message.returnType.type === null) { return undefined } @@ -108,7 +145,7 @@ function sendGetMessage(address: Uint8Array) { function sendFlipMessage(address: Uint8Array) { const message = findContractMessageByLabel("flip")! - const value = sendMessageDryRunContractCall(address, message) + const value = preSubmitContractCallDryRunGasEstimate(address, message) .next(({ gasRequired }) => { return { type: "call", @@ -122,7 +159,7 @@ function sendFlipMessage(address: Uint8Array) { storageDepositLimit: undefined, } }) - return C.extrinsic(client)({ + const tx = C.extrinsic(client)({ sender: T.alice.address, call: C.Z.rec({ type: "Contracts", @@ -130,17 +167,25 @@ function sendFlipMessage(address: Uint8Array) { }), }) .signed(T.alice.sign) - .watch(({ end }) => - (status) => { - // .watch emits a single inBlock event - if (typeof status !== "string" && status.inBlock) { - return end(status.inBlock) - } else if (C.rpc.known.TransactionStatus.isTerminal(status)) { - return end(new Error()) - } - return + const finalizedIn = tx.watch(({ end }) => + (status) => { + if (typeof status !== "string" && (status.inBlock ?? status.finalized)) { + return end(status.inBlock ?? status.finalized) + } else if (C.rpc.known.TransactionStatus.isTerminal(status)) { + return end(new Error()) } + return + } + ) + return C.Z.ls(finalizedIn, C.events(tx, finalizedIn)).next(([finalizedIn, events]) => { + const extrinsicFailed = events.some((e) => + e.event?.type === "System" && e.event?.value?.type === "ExtrinsicFailed" ) + if (extrinsicFailed) { + return new Error("extrinsic failed") + } + return finalizedIn + }) } function findContractConstructorByLabel(label: string) { diff --git a/frame_metadata/Contract.ts b/frame_metadata/Contract.ts index 524dbdf6a..0202d0289 100644 --- a/frame_metadata/Contract.ts +++ b/frame_metadata/Contract.ts @@ -218,7 +218,7 @@ export const $contractsApiCallArgs: $.Codec = $.tuple( $.uint8Array, ) -export interface ContractsApiCallReturn { +export interface ContractsApiCallResult { gasConsumed: Weight gasRequired: Weight storageDeposit: { @@ -234,7 +234,7 @@ export interface ContractsApiCallReturn { data: Uint8Array } } -export const $contractsApiCallReturn: $.Codec = $.object( +export const $contractsApiCallResult: $.Codec = $.object( // gas_consumed ["gasConsumed", $weightCodec], // gas_required @@ -259,3 +259,88 @@ export const $contractsApiCallReturn: $.Codec = $.object ), ], ) + +export type ContractsApiInstantiateArgs = [ + origin: Uint8Array, + balance: bigint, + gasLimit: Weight | undefined, + storageDepositLimit: bigint | undefined, + codeOrHash: { + type: "Upload" | "Existing" + value: Uint8Array + }, + data: Uint8Array, + salt: Uint8Array, +] +export const $contractsApiInstantiateArgs: $.Codec = $.tuple( + // origin + $.sizedUint8Array(32), + // balance + $balanceCodec, + // gasLimit + $.option($weightCodec), + // storageDepositLimit + $.option($balanceCodec), + // codeOrHash + $.taggedUnion("type", [ + // code + ["Upload", ["value", $.uint8Array]], + // hash + ["Existing", ["value", $.sizedUint8Array(32)]], + ]), + // data + $.uint8Array, + // salt + $.uint8Array, +) + +export interface ContractsApiInstantiateResult { + gasConsumed: Weight + gasRequired: Weight + storageDeposit: { + type: "Refund" + value: bigint + } | { + type: "Charge" + value: bigint + } + debugMessage: string + result: { + result: { + flags: number + data: Uint8Array + } + accountId: Uint8Array + } +} +export const $contractsApiInstantiateResult: $.Codec = $.object( + // gas_consumed + ["gasConsumed", $weightCodec], + // gas_required + ["gasRequired", $weightCodec], + // storage_deposit + [ + "storageDeposit", + $.taggedUnion("type", [ + ["Refund", ["value", $balanceCodec]], + ["Charge", ["value", $balanceCodec]], + ]), + ], + // debug_message + ["debugMessage", $.str], + // result + [ + "result", + $.object( + [ + "result", + $.object( + ["flags", $.u32], + // TODO: improve result error coded + ["data", $.result($.uint8Array, $.never)], + ), + ], + ["accountId", $.sizedUint8Array(32)], + ), + ], +) From ecf86237e2d65e5c7bef3250edd73c52bf7acea6 Mon Sep 17 00:00:00 2001 From: Matias Volpe Date: Wed, 14 Dec 2022 11:54:07 -0300 Subject: [PATCH 06/21] chore: add base58 dep comment --- deps/std/encoding/base58.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deps/std/encoding/base58.ts b/deps/std/encoding/base58.ts index 66333c9b0..b2361fcb0 100644 --- a/deps/std/encoding/base58.ts +++ b/deps/std/encoding/base58.ts @@ -1,2 +1,2 @@ -// export * from "https://deno.land/std@0.167.0/encoding/base58.ts" -export * from "https://raw.githubusercontent.com/kratico/deno_std/main/encoding/base58.ts" +// TODO: use std@0.168.0/encoding/base58.ts when https://github.com/denoland/deno_std/pull/2982 is released +export * from "https://raw.githubusercontent.com/denoland/deno_std/01696ce149463f498301782ac5e9ee322a86182c/encoding/base58.ts" From be1009308ff417ad46ded014f947487328490232 Mon Sep 17 00:00:00 2001 From: Matias Volpe Date: Wed, 14 Dec 2022 11:58:53 -0300 Subject: [PATCH 07/21] chore: clean up --- examples/smart_contract/codec.ts | 48 -------------------------------- 1 file changed, 48 deletions(-) delete mode 100644 examples/smart_contract/codec.ts diff --git a/examples/smart_contract/codec.ts b/examples/smart_contract/codec.ts deleted file mode 100644 index 8081d6533..000000000 --- a/examples/smart_contract/codec.ts +++ /dev/null @@ -1,48 +0,0 @@ -import * as C from "http://localhost:5646/@local/mod.ts" - -const $balanceCodec = C.$.u128 -const $weightCodec = C.$.object( - ["ref_time", C.$.compact(C.$.u64)], - ["proof_size", C.$.compact(C.$.u64)], -) - -export const $contractsApiCallArgs = C.$.tuple( - // origin - C.$.sizedUint8Array(32), - // dest - C.$.sizedUint8Array(32), - // balance - $balanceCodec, - // weight - C.$.option($weightCodec), - // storage_deposit_limit - C.$.option($balanceCodec), - // data - C.$.uint8Array, -) - -export const $contractsApiCallReturn = C.$.object( - // gas_consumed - ["gas_consumed", $weightCodec], - // gas_required - ["gas_required", $weightCodec], - // storage_deposit - [ - "storage_deposit", - C.$.taggedUnion("type", [ - ["Refund", ["value", $balanceCodec]], - ["Charge", ["value", $balanceCodec]], - ]), - ], - // debug_message - ["debug_message", C.$.str], - // result - [ - "result", - C.$.object( - ["flags", C.$.u32], - // TODO: improve result error coded - ["data", C.$.result(C.$.uint8Array, C.$.never)], - ), - ], -) From 6e0db2f38f91d53c86ebffb36337603f5553e7ff Mon Sep 17 00:00:00 2001 From: Matias Volpe Date: Wed, 14 Dec 2022 12:09:38 -0300 Subject: [PATCH 08/21] chore: add derived contract address from dry run --- examples/smart_contract.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/examples/smart_contract.ts b/examples/smart_contract.ts index 33c1f142c..49b79eb81 100644 --- a/examples/smart_contract.ts +++ b/examples/smart_contract.ts @@ -30,7 +30,9 @@ function instantiateContractTx() { const constructor = findContractConstructorByLabel("default")! const salt = Uint8Array.from(Array.from([0, 0, 0, 0]), () => Math.floor(Math.random() * 16)) const value = preSubmitContractInstantiateDryRunGasEstimate(constructor, contract.wasm, salt) - .next(({ gasRequired }) => { + .next(({ gasRequired, result: { accountId } }) => { + // the contract address derived from the code hash and the salt + console.log("Derived contract address", U.ss58.encode(42, accountId)) return { type: "instantiateWithCode", value: 0n, From fc6e3248a82ed6c366b292d98fc7c57647caf32e Mon Sep 17 00:00:00 2001 From: Matias Volpe Date: Wed, 14 Dec 2022 15:48:00 -0300 Subject: [PATCH 09/21] feat: add SmartContract class --- examples/smart_contract.ts | 258 ++++++++++++++--------- examples/smart_contract/flipper.contract | 2 +- examples/smart_contract/flipper.wasm | Bin 15044 -> 16990 bytes examples/smart_contract/metadata.json | 193 ++++++++++++++++- 4 files changed, 352 insertions(+), 101 deletions(-) diff --git a/examples/smart_contract.ts b/examples/smart_contract.ts index 49b79eb81..df0bc6747 100644 --- a/examples/smart_contract.ts +++ b/examples/smart_contract.ts @@ -20,11 +20,6 @@ const contract = await getContract( const contractAddress = U.throwIfError(await instantiateContractTx().run()) console.log("Deployed Contract address", U.ss58.encode(42, contractAddress)) -console.log("get message", U.throwIfError(await sendGetMessage(contractAddress).run())) -console.log("flip message in block", U.throwIfError(await sendFlipMessage(contractAddress).run())) -console.log("get message", U.throwIfError(await sendGetMessage(contractAddress).run())) - -await zombienet.close() function instantiateContractTx() { const constructor = findContractConstructorByLabel("default")! @@ -101,103 +96,10 @@ function preSubmitContractInstantiateDryRunGasEstimate( }) } -function preSubmitContractCallDryRunGasEstimate( - address: Uint8Array, - message: C.M.ContractMetadata.Message | C.M.ContractMetadata.Constructor, -) { - const key = U.hex.encode($contractsApiCallArgs.encode([ - T.alice.publicKey, - address, - 0n, - undefined, - undefined, - U.hex.decode(message.selector), - ])) - return C.state.call(client)( - "ContractsApi_call", - key, - ) - .next((encodedResponse) => { - return $contractsApiCallResult.decode(U.hex.decode(encodedResponse)) - }) -} - -function sendGetMessage(address: Uint8Array) { - const message = findContractMessageByLabel("get")! - const key = U.hex.encode($contractsApiCallArgs.encode([ - T.alice.publicKey, - address, - 0n, - undefined, - undefined, - U.hex.decode(message.selector), - ])) - return C.state.call(client)( - "ContractsApi_call", - key, - ) - .next((encodedResponse) => { - const response = $contractsApiCallResult.decode(U.hex.decode(encodedResponse)) - if (message.returnType.type === null) { - return undefined - } - return contract.deriveCodec(message.returnType.type).decode(response.result.data) - }) -} - -function sendFlipMessage(address: Uint8Array) { - const message = findContractMessageByLabel("flip")! - const value = preSubmitContractCallDryRunGasEstimate(address, message) - .next(({ gasRequired }) => { - return { - type: "call", - dest: C.MultiAddress.Id(address), - value: 0n, - data: U.hex.decode(message.selector), - gasLimit: { - refTime: gasRequired.refTime, - proofSize: gasRequired.proofSize, - }, - storageDepositLimit: undefined, - } - }) - const tx = C.extrinsic(client)({ - sender: T.alice.address, - call: C.Z.rec({ - type: "Contracts", - value, - }), - }) - .signed(T.alice.sign) - const finalizedIn = tx.watch(({ end }) => - (status) => { - if (typeof status !== "string" && (status.inBlock ?? status.finalized)) { - return end(status.inBlock ?? status.finalized) - } else if (C.rpc.known.TransactionStatus.isTerminal(status)) { - return end(new Error()) - } - return - } - ) - return C.Z.ls(finalizedIn, C.events(tx, finalizedIn)).next(([finalizedIn, events]) => { - const extrinsicFailed = events.some((e) => - e.event?.type === "System" && e.event?.value?.type === "ExtrinsicFailed" - ) - if (extrinsicFailed) { - return new Error("extrinsic failed") - } - return finalizedIn - }) -} - function findContractConstructorByLabel(label: string) { return contract.metadata.V3.spec.constructors.find((c) => c.label === label) } -function findContractMessageByLabel(label: string) { - return contract.metadata.V3.spec.messages.find((c) => c.label === label) -} - async function getContract(wasmFile: string, metadataFile: string) { const wasm = await Deno.readFile(wasmFile) const metadata = C.M.ContractMetadata.normalize(JSON.parse( @@ -213,3 +115,163 @@ function getFilePath(relativeFilePath: string) { relativeFilePath, ) } + +class SmartContract { + readonly deriveCodec + + constructor( + readonly metadata: C.M.ContractMetadata, + readonly contractAddress: Uint8Array, + ) { + this.deriveCodec = C.M.DeriveCodec(metadata.V3.types) + } + + call( + origin: Uint8Array, + messageLabel: string, + args: Args, + ) { + const message = this.#getMessageByLabel(messageLabel)! + const [$args, $result] = this.#getMessageCodecs(message) + const data = $args.encode([U.hex.decode(message.selector), ...args]) + const callData = U.hex.encode($contractsApiCallArgs.encode([ + origin, + this.contractAddress, + 0n, + undefined, + undefined, + data, + ])) + return C.state.call(client)( + "ContractsApi_call", + callData, + ) + .next((encodedResponse) => { + const response = $contractsApiCallResult.decode(U.hex.decode(encodedResponse)) + if (message.returnType === null) { + return undefined + } + return $result.decode(response.result.data) + }) + } + + tx( + origin: Uint8Array, + messageLabel: string, + args: Args, + sign: C.Z.$, + ) { + const message = this.#getMessageByLabel(messageLabel)! + const [$args, _] = this.#getMessageCodecs(message) + const data = $args.encode([U.hex.decode(message.selector), ...args]) + const value = this.#preSubmitContractCallDryRunGasEstimate(origin, data) + .next(({ gasRequired }) => { + return { + type: "call", + dest: C.MultiAddress.Id(this.contractAddress), + value: 0n, + data, + gasLimit: { + refTime: gasRequired.refTime, + proofSize: gasRequired.proofSize, + }, + storageDepositLimit: undefined, + } + }) + const tx = C.extrinsic(client)({ + sender: C.MultiAddress.Id(origin), + call: C.Z.rec({ + type: "Contracts", + value, + }), + }) + .signed(sign) + const finalizedIn = tx.watch(({ end }) => + (status) => { + if (typeof status !== "string" && (status.inBlock ?? status.finalized)) { + return end(status.inBlock ?? status.finalized) + } else if (C.rpc.known.TransactionStatus.isTerminal(status)) { + return end(new Error()) + } + return + } + ) + return C.Z.ls(finalizedIn, C.events(tx, finalizedIn)) + } + + // TODO: codegen each contract message as a method + + #getMessageByLabel(label: string) { + return this.metadata.V3.spec.messages.find((c) => c.label === label) + } + + #getMessageCodecs( + message: C.M.ContractMetadata.Message, + ): [C.$.Codec, C.$.Codec] { + const argCodecs = [ + // message selector + C.$.sizedUint8Array(U.hex.decode(message.selector).length), + // message args + ...message.args.map((arg) => this.deriveCodec(arg.type.type)), + ] + const $result = message.returnType !== null + ? this.deriveCodec(message.returnType.type) + : C.$.constant(null) + // @ts-ignore ... + return [C.$.tuple(...argCodecs), $result] + } + + #preSubmitContractCallDryRunGasEstimate( + origin: Uint8Array, + data: Uint8Array, + ) { + const callData = U.hex.encode($contractsApiCallArgs.encode([ + origin, + this.contractAddress, + 0n, + undefined, + undefined, + data, + ])) + return C.state.call(client)( + "ContractsApi_call", + callData, + ) + .next((encodedResponse) => { + return $contractsApiCallResult.decode(U.hex.decode(encodedResponse)) + }) + } +} + +const flipperContract = new SmartContract(contract.metadata, contractAddress) +console.log(".get", await flipperContract.call(T.alice.publicKey, "get", []).run()) +console.log( + "block hash and events", + U.throwIfError(await flipperContract.tx(T.alice.publicKey, "flip", [], T.alice.sign).run())[0], +) +console.log(".get", await flipperContract.call(T.alice.publicKey, "get", []).run()) +console.log(".get_count", await flipperContract.call(T.alice.publicKey, "get_count", []).run()) +console.log( + ".inc block hash", + U.throwIfError(await flipperContract.tx(T.alice.publicKey, "inc", [], T.alice.sign).run())[0], +) +console.log( + ".inc block hash", + U.throwIfError(await flipperContract.tx(T.alice.publicKey, "inc", [], T.alice.sign).run())[0], +) +console.log(".get_count", await flipperContract.call(T.alice.publicKey, "get_count", []).run()) +console.log( + ".inc_by(3) block hash", + U.throwIfError(await flipperContract.tx(T.alice.publicKey, "inc_by", [3], T.alice.sign).run())[0], +) +console.log(".get_count", await flipperContract.call(T.alice.publicKey, "get_count", []).run()) +console.log( + ".m1(2,true) (multiple args/results)", + await flipperContract.call(T.alice.publicKey, "m1", [2, true]).run(), +) +console.log( + ".m2(3,false) (multiple args/results)", + await flipperContract.call(T.alice.publicKey, "m1", [3, false]).run(), +) + +await zombienet.close() diff --git a/examples/smart_contract/flipper.contract b/examples/smart_contract/flipper.contract index 7b5e7984e..cd1c91b6b 100644 --- a/examples/smart_contract/flipper.contract +++ b/examples/smart_contract/flipper.contract @@ -1 +1 @@ -{"source":{"hash":"0x2345709e061bfa0d374eaf0c25f19c8dce43ac11362c55196e1ecf465781b750","language":"ink! 3.4.0","compiler":"rustc 1.67.0-nightly","wasm":"0x0061736d01000000014e0d60037f7f7f017f60027f7f017f60027f7f0060057f7f7f7f7f0060037f7f7f0060047f7f7f7f0060017f0060000060047f7f7f7f017f60017f017e60017f017f6000017f60067f7f7f7f7f7f0002a30107057365616c30127365616c5f64656275675f6d6573736167650001057365616c30107365616c5f7365745f73746f726167650004057365616c30107365616c5f6765745f73746f726167650000057365616c300a7365616c5f696e7075740002057365616c300b7365616c5f72657475726e0004057365616c30167365616c5f76616c75655f7472616e73666572726564000203656e76066d656d6f727902010210033b3a0002010601020a00020303040b02070607030100000401010006070206010903050101010308050803040101040000030508050101010101050c040501700110100501000608017f01418080040b071102066465706c6f7900140463616c6c00160915010041010b0f0a30313c2723393a223d1a1c1d3b240acf513a2b01017f037f2002200346047f200005200020036a200120036a2d00003a0000200341016a21030c010b0b0b7901017f230041406a22022400200241206a200141186a290000370300200241186a200141106a290000370300200241106a200141086a29000037030020024201370328200220012900003703082002419ea104360230200242808001370234200241086a200241306a2000100841011001200241406b24000b7701037f230041106b220224002000280204210320002802002104200220013a000f200241012004200341c49a04100f200228020020022802042002410f6a410141d49a041010200345044041a49904412341e49a041011000b2000200341016b3602042000200441016a360200200241106a240020040b5201017f230041206b220124002001410c6a4101360200200141146a4101360200200141909d04360208200141003602002001410136021c200120003602182001200141186a360210200141948304100b000b910101017f230041306b22022400200241146a41013602002002411c6a4101360200200241909d043602102002410036020820024102360224200220002d0000410274220041eca0046a28020036022c200220004180a1046a280200360228200141046a28020021002002200241206a3602182002200241286a36022020012802002000200241086a1033200241306a24000b840301037f230041206b22032400200341013a00182003200136021420032000360210200341dc890436020c200341909d04360208230041406a220224002002200341086a36020c2002410436022420022002410c6a360220410021004104210402400240024002400240024003402000200441c899046a2802006a22012000490d0120012100200441086a22044114470d000b4100210041012104024020014110490d002001200120016a22034b200345720d0020034100480d022002200310212003210020022802002204450d060b2002410036021820022004360214200220003602102002410136023c20024102360234200241c89904360230200241003602282002200241206a360238200241106a200241286a10180d02419ca1042d0000450440419da1042d00004101710d060b2002280214200228021810004109470d030c040b41c08404411c418499041011000b1020000b41c086044133200241286a4184850441e087041017000b419ca10441013a00000b419da10441013a00000b000b4001017f230041106b22012400200141003a000f20002001410f6a4101100d047f4102054101410220012d000f22004101461b410020001b0b200141106a24000b6001047f230041106b22032400200028020422042002492205450440200341086a4100200220002802002206103e200120022003280208200328020c41a4a00410102003200220042006103e200020032903003702000b200341106a240020050b4701017f230041106b220224002002410036020c024020012002410c6a4104100d4504402000200228020c360001200041003a00000c010b200041013a00000b200241106a24000b2200200120034d044020002001360204200020023602000f0b200120032004102f000b8501002001200346044020002002200110061a0f0b230041306b220024002000200336020420002001360200200041146a41033602002000411c6a41023602002000412c6a4105360200200041ec920436021020004100360208200041053602242000200041206a360218200020003602282000200041046a360220200041086a2004100b000b5001017f230041206b220324002003410c6a4101360200200341146a4100360200200341909d04360210200341003602002003200136021c200320003602182003200341186a36020820032002100b000b6c02027f027e230041206b22002400200041086a220142003703002000420037030020004110360214200020003602102000411036021c20002000411c6a1005200041106a200028021c10132001290300210220002903002103200041206a2400410541042002200384501b0b3501017f230041106b22022400200241086a20012000280200200028020441dc9b04100f20002002290308370200200241106a24000bd00301057f230041306b220024002000027f02400240101241ff0171410546044020004180800136022c2000419ea104360228200041286a1015200020002903283703082000200041086a100e20002d00000d022000280001220141187621022001411076210320014108762104027f200141ff01712201419b01470440200141ed0147200441ff017141cb004772200341ff0171419d0147720d0441022002411b460d011a0c040b200441ff017141ae0147200341ff0171419d014772200241de0047720d03200041086a100c41ff017122014102460d0320014101710b2101101241ff01712102024002402001410247044020024105460d010c040b20024105470d03200041206a4200370300200041186a4200370300200041106a4200370300200042003703084100200041086a10070c010b200041206a4200370300200041186a4200370300200041106a4200370300200042003703082001200041086a10070b200041306a24000f0b200041043a0008200041086a1009000b41040c010b41030b3a0000200041146a41013602002000411c6a4101360200200041ec8304360210200041003602082000410136022c2000200041286a36021820002000360228200041086a41948304100b000b3301017f230041106b220124002001200028020436020c20002802002001410c6a10032000200128020c1013200141106a24000b8a0601057f230041d0006b2200240002400240024002400240101241ff01712201410546044020004180800136023c2000419ea104360238200041386a101520002000290338370308200041306a200041086a100e024020002d00300d002000280031220141187621022001411076210320014108762104200141ff01712201412f470440200141e30047200441ff0171413a4772200341ff017141a50147720d0141012101200241d100470d010c030b200441ff017141860147200341ff017141db0047720d0041002101200241d901460d020b410321010c020b200020013a0008200041086a1009000b200041106a4200370300200041186a4200370300200041206a420037030020004200370308200042013703282000418080013602342000419ea104360230200041808001360238200041086a419ea104200041386a10022102200041306a200028023810130240024002402002410c4f0d00200241027441bca0046a2802000e0402000001000b200041c4006a4101360200200041cc006a4100360200200041d48204360240200041909d0436024820004100360238200041386a41dc8204100b000b230041106b220124002001411736020c200141988104360208230041206b220024002000410c6a4101360200200041146a4101360200200041909d04360208200041003602002000410236021c2000200141086a3602182000200041186a360210200041b08104100b000b20002000290330370338200041386a100c41ff017122024102460d03101241ff017121032001044020034105460d02410421010c010b4104210120034105460d020b200020013a0030200041146a41013602002000411c6a4101360200200041988404360210200041003602082000410136023c2000200041386a3602182000200041306a360238200041086a41948304100b000b20024541a483041007200041d0006a24000f0b230041106b220024002000419ea104360200200042808001370204410020002002410047100841011004000b200041003a0038418080044127200041386a41c08104418881041017000b860101017f230041406a220524002005200136020c200520003602082005200336021420052002360210200541246a41023602002005412c6a41023602002005413c6a4103360200200541908a0436022020054100360218200541023602342005200541306a3602282005200541106a3602382005200541086a360230200541186a2004100b000b5501017f230041206b2202240020022000360204200241186a200141106a290200370300200241106a200141086a29020037030020022001290200370308200241046a41a08404200241086a1019200241206a24000bee0301057f230041406a22032400200341033a003820034280808080800437033020034100360228200341003602202003200136021c20032000360218027f0240024020022802002201450440200241146a28020022004103742105200041ffffffff017121072002280210210441002101034020012005460d02200228020820016a220041046a28020022060440200328021820002802002006200328021c28020c1100000d040b200141086a2101200428020020042802042106200441086a2104200341186a2006110100450d000b0c020b200228020422074105742100200741ffffff3f71210703402000450d01200228020820046a220541046a28020022060440200328021820052802002006200328021c28020c1100000d030b20032001411c6a2d00003a00382003200141146a290200370330200341106a200228021022052001410c6a103220032003290310370320200341086a2005200141046a103220032003290308370328200441086a2104200041206b210020012802002106200141206a2101200520064103746a2205280200200341186a2005280204110100450d000b0c010b2002410c6a28020020074b04402003280218200228020820074103746a22002802002000280204200328021c28020c1100000d010b41000c010b41010b200341406b24000b0f00200028020020012002101b41000b5801017f20022000280200200028020822036b4b0440200020032002101e101f200028020821030b200028020420036a2001200210061a2003200220036a22014b044041c08404411c41f088041011000b200020013602080bbe0201027f230041106b220224000240024002400240200028020022002002410c6a027f0240024020014180014f04402002410036020c2001418010490d012001418080044f0d0220022001413f71418001723a000e20022001410c7641e001723a000c20022001410676413f71418001723a000d41030c030b200028020822032000280200460d030c040b20022001413f71418001723a000d2002200141067641c001723a000c41020c010b20022001413f71418001723a000f20022001410676413f71418001723a000e20022001410c76413f71418001723a000d2002200141127641077141f001723a000c41040b101b0c020b200020034101101e101f200028020821030b200028020420036a20013a0000200341016a2201450d01200020013602080b200241106a240041000f0b41c08404411c41e088041011000b4a01017f230041206b220224002000280200200241186a200141106a290200370300200241106a200141086a29020037030020022001290200370308200241086a1018200241206a24000b990401067f230041206b220324000240027f41002001200120026a22014b0d001a2000280200220220026a22052002490d012005200120012005491b22014108200141084b1b2201417f73411f7621040240200204402003410136021820032002360214200320002802043602100c010b200341003602180b200341106a2106230041106b220524002003027f0240027f0240200404400240200141004e044020062802080d012005200110212005280204210220052802000c040b0c040b20062802042208450440200541086a20011021200528020c210220052802080c030b2001210241004194a104280200220420016a22072004490d021a200628020021064198a1042802002007490440200141ffff036a220741107640002202417f46200241ffff0371200247720d022002411074220420074180807c716a22022004490d024198a1042002360200200121024100200120046a22072004490d031a0b4194a104200736020041002004450d021a20042006200810060c020b200320013602040c020b2001210241000b2204044020032004360204200341086a200236020041000c020b20032001360204200341086a410136020041010c010b200341086a410036020041010b360200200541106a240020032802004504402003280204210220002001360200200020023602044181808080780c010b200341086a2802000b200341206a24000f0b41e084044121418486041011000b1b00024020004181808080784704402000450d01000b0f0b1020000b4601017f230041206b22002400200041146a41013602002000411c6a4100360200200041a88604360210200041909d0436021820004100360208200041086a41b08604100b000ba10101027f027f41004194a104280200220320016a22022003490d001a02404198a1042802002002490440200141ffff036a22022001490d012002411076220240002203417f46200341ffff0371200347720d012003411074220320024110746a22022003490d014198a10420023602004100200120036a22022003490d021a0b4194a104200236020020030c010b41000b210220002001360204200020023602000b0300010b0e0020002802001a03400c000b000b0c0042abf2ce83adf3f7da440bb20101017f230041106b2205240020022003490440230041306b220024002000200236020420002003360200200041146a41023602002000411c6a41023602002000412c6a4105360200200041e88f0436021020004100360208200041053602242000200041206a3602182000200041046a36022820002000360220200041086a2004100b000b200541086a2003200220011026200528020c21012000200528020836020020002001360204200541106a24000b1400200020012002200341849f0441a08904103f0bd806020b7f027e230041406a2203240020002802002202ad210d0240024002400240024002400240024020024190ce004f044041272100200d210e0240034020004104490d01200341196a20006a220241046b200e200e4290ce0080220d4290ce007e7da7220441ffff037141e4006e220641017441978b046a2f00003b0000200241026b2004200641e4006c6b41ffff037141017441978b046a2f00003b0000200041046b2100200e42ffc1d72f56200d210e0d000b200da7220241e3004d0d0320004102490d090c020b0c080b41272100200241e3004b0d002002410a490d040c020b200041026b2200200341196a6a200da72202200241ffff037141e4006e220241e4006c6b41ffff037141017441978b046a2f00003b00000b2002410a490d01200041024f0d000c050b200041026b2200200341196a6a200241017441978b046a2f00003b00000c020b2000450d030b200041016b2200200341196a6a200241306a3a00000b200041274b0d01412820006b412720006b22062001280218220541017122071b2102410021042005410471044041909d042104200241909d0441909d04102820026a22024b0d010b412b418080c40020071b2107200341196a20006a2108024020012802084504404101210020012802002202200141046a280200220120072004102b0d01200220082006200128020c11000021000c010b024020022001410c6a28020022094904402005410871450d01200128021c210b2001413036021c20012d0020210c41012100200141013a002020012802002205200141046a280200220a20072004102b0d02200341106a2001200920026b4101102c20032802142202418080c400460d022003280210200520082006200a28020c1100000d0220022005200a102d0d022001200c3a00202001200b36021c410021000c020b4101210020012802002202200141046a280200220120072004102b0d01200220082006200128020c11000021000c010b41012100200341086a2001200920026b4101102c200328020c2205418080c400460d00200328020820012802002202200141046a280200220120072004102b0d00200220082006200128020c1100000d00200520022001102d21000b200341406b240020000f0b41808904411c41d08d041011000b41a089044121419499041011000ba704010a7f230041106b2203240002400240200020016b22024110490d002002200141036a417c7120016b220049200041044b720d00200220006b22044104490d002001200010292206200020016a22082004417c716a200441037110296a220220064f0440200441027621050240024003402005450d05200320082005200541c001200541c001491b418c9104102a200328020c21052003280208210820032003280200200328020422002000417c71418c9204102a200328020c210920032802082107024020032802042200450440410021010c010b2003280200220420004102746a210a4100210103402004220641106a2104410021000240034020012001200020066a280200220b417f73410776200b410676724181828408716a22014d0440200041046a22004110470d010c020b0b41808904411c418494041011000b2004200a470d000b0b20022002200141087641ff81fc0771200141ff81fc07716a418180046c4110766a22024b0d012009450d000b200941027421004100210103402001200120072802002204417f734107762004410676724181828408716a22014b0d02200741046a2107200041046b22000d000b20022002200141087641ff81fc0771200141ff81fc07716a418180046c4110766a22024d0d0441808904411c41b494041011000b41808904411c419494041011000b41808904411c41a494041011000b41808904411c41f493041011000b20012002102921020b200341106a240020020b4601017f200145044041000f0b024003402002200220002c000041bf7f4a6a22024b0d01200041016a2100200141016b22010d000b20020f0b41808904411c418499041011000b3e00200220034f044020002003360204200020013602002000410c6a200220036b3602002000200120034102746a3602080f0b41a49904412320041011000b39000240027f2002418080c40047044041012000200220012802101101000d011a0b20030d0141000b0f0b200020034100200128020c1100000bae0101027f20022104024002400240200320012d0020220320034103461b41ff0171220341016b0e03010001020b200241016a2203044020034101762104200241017621030c020b41808904411c41e08d041011000b41002104200221030b200341016a2102200128021c2103200128020421052001280200210102400340200241016b2202450d01200120032005280210110100450d000b418080c40021030b20002003360204200020043602000b3201017f027f0340200020002004460d011a200441016a2104200220012003280210110100450d000b200441016b0b2000490b4b01017f230041106b22052400200120034d0440200541086a4100200120021026200528020c21012000200528020836020020002001360204200541106a24000f0b200120032004102f000b7501017f230041306b220324002003200136020420032000360200200341146a41023602002003411c6a41023602002003412c6a410536020020034188900436021020034100360208200341053602242003200341206a3602182003200341046a36022820032003360220200341086a2002100b000bea04010b7f230041106b2209240020002802042104200028020021030240024002402001280208220b410147200128021022024101477145044020024101470d02200320046a210c200141146a28020041016a210a410021022003210003402000200c460d03027f024020002c0000220641004e0440200041016a2105200641ff017121070c010b20002d0001413f7121052006411f7121072006415f4d044020074106742005722107200041026a21050c010b20002d0002413f7120054106747221082006417049044020082007410c74722107200041036a21050c010b200041046a210520022106418080c4002007411274418080f0007120002d0003413f71200841067472722207418080c400460d011a0b2002200520006b6a22062002490d0320070b2108200a41016b220a044020052100200621022008418080c400470d010c040b0b2008418080c400460d02024002402002450d00200220044f04404100210020022004460d010c020b41002100200220036a2c00004140480d010b200321000b2002200420001b21042000200320001b21030c020b200128020020032004200128020428020c11000021000c020b41808904411c41b495041011000b200b450440200128020020032004200128020428020c11000021000c010b2001410c6a2802002200200320046a2003102822024b0440200941086a2001200020026b4100102c41012100200928020c2202418080c400460d0120092802082001280200220520032004200141046a280200220128020c1100000d01200220052001102d21000c010b200128020020032004200128020428020c11000021000b200941106a240020000b140020002802002001200028020428020c1101000b5501027f0240027f02400240200228020041016b0e020103000b200241046a0c010b200120022802044103746a22012802044106470d0120012802000b2802002104410121030b20002004360204200020033602000b4901017f230041206b22032400200341186a200241106a290200370300200341106a200241086a2902003703002003200229020037030820002001200341086a1019200341206a24000bda08010b7f23004190016b22032400200341003b0184012003410a3602800120034281808080a00137037820032002360274200341003602702003200236026c200320013602682003200236026420034100360260200028020421062000280200210720002802082108200341fc006a2109027f0340024002400240024020032d008501450440200341d8006a2003280268220c200328026c2003280270200328027410350240024020032802582201450d00200328025c2100034002400240024002400240027f0240024002400240200328027822020440200220096a41016b2d00002104200041084f04402001200141036a417c712202460440200041086b210a410021020c040b200341d0006a200220016b22022000200020024b1b22022001200041e48e04102e200341c8006a200420032802502003280254103620032802484101470d02200328024c21010c050b200341306a20042001200010362003280234210120032802300c050b41a08904412141cc97041011000b2002200041086b220a4b0d010b200441818284086c210b0340200241046a22052002490d04200120026a280200200b73220d417f73200d41818284086b71200120056a280200200b732205417f73200541818284086b7172418081828478710d012002200241086a22024b0d072002200a4d0d000b0b200341406b20012000200241948f041025200341386a2004200328024020032802441036410020032802384101470d011a2002200328023c6a220120024f0d0041808904411c41a48f041011000b41010b4101460440200141016a2200450d022000200328027022006a22022000490d0320032002360270200220032802782200490d05200341286a2003280268200328026c200220006b2002103520032802282202450d05200328022c2100200341206a20032802782009410441fc9704102e20022000200328022020032802241037450d05200341186a200328026020032802702200200c103820032000360260200328021c2102200328021821000c080b200320032802743602700c060b41808904411c41f48e041011000b41808904411c41dc97041011000b41808904411c41ec97041011000b41808904411c41848f041011000b200341106a2003280268200328026c20032802702003280274103520032802142100200328021022010d000b0b4100210020032d0085010d00024020032d008401044020032802642101200328026021040c010b2003280264220120032802602204490d0420012004460d010b200341013a008501200341086a2004200120032802681038200328020c2102200328020821000b20000d010b41000c050b20082d0000450d01200741a08a044104200628020c110000450d010c020b41a08904412141c495041011000b2003410a36028c0120082002047f200320002002200241016b419c920410252003418c016a41012003280200200328020410370541000b3a0000200720002002200628020c110000450d010b0b41010b20034190016a24000b4c01037f230041106b220524002002200449200320044b72450440200541086a2003200420011026200528020c2107200528020821060b2000200736020420002006360200200541106a24000b5701027f024002402003450440410021030c010b200141ff017121054101210103402005200220046a2d0000460440200421030c030b2003200441016a2204470d000b0b410021010b20002003360204200020013602000b4d01017f2001200346047f027f034041002001450d011a200141016b210120022d0000210320002d00002104200041016a2100200241016a210220032004460d000b200420036b0b0541010b450b1400200020012002200341c8960441a08904103f0b5801027f230041206b22022400200128020421032001280200200241186a2000280200220041106a290200370300200241106a200041086a290200370300200220002902003703082003200241086a1019200241206a24000b0b002000280200200110300b1800200128020041b4a0044105200128020428020c1100000b990301037f230041406a22022400200028020021034101210002402001280200220441ec8904410c200141046a280200220128020c1100000d0002402003280208220004402002200036020c200241346a4102360200410121002002413c6a4101360200200241fc890436023020024100360228200241073602142002200241106a36023820022002410c6a36021020042001200241286a1033450d010c020b20032802002200200328020428020c11090042c8b5e0cfca86dbd3897f520d002002200036020c200241346a4102360200410121002002413c6a4101360200200241fc890436023020024100360228200241083602142002200241106a36023820022002410c6a36021020042001200241286a10330d010b200328020c21002002411c6a4103360200200241246a41033602002002413c6a4105360200200241346a4105360200200241c489043602182002410036021020022000410c6a3602382002200041086a3602302002410236022c200220003602282002200241286a36022020042001200241106a103321000b200241406b240020000b980401047f230041106b22022400024002400240024002400240024002400240024002400240024020002d000041016b0e0b0102030405060708090a0b000b4101210020012802002203418a9d0441062001280204220528020c22041100000d0b024020012d0018410471450440200341a88a04410120041100000d0d200341b4a00441052004110000450d010c0d0b200341a68a04410220041100000d0c2002200536020420022003360200200241013a000f20022002410f6a360208200241b4a004410510340d0c200241a48a04410210340d0c0b200341c189044101200411000021000c0b0b200128020041fd9c04410d200128020428020c11000021000c0a0b200128020041ef9c04410e200128020428020c11000021000c090b200128020041e49c04410b200128020428020c11000021000c080b200128020041ca9c04411a200128020428020c11000021000c070b200128020041bc9c04410e200128020428020c11000021000c060b200128020041ac9c044110200128020428020c11000021000c050b200128020041a09c04410c200128020428020c11000021000c040b200128020041959c04410b200128020428020c11000021000c030b2001280200418e9c044107200128020428020c11000021000c020b200128020041ff9b04410f200128020428020c11000021000c010b200128020041ec9b044113200128020428020c11000021000b200241106a240020000b1400200020012002200341849f0441a09f04103f0b2800200120024d04402000200220016b3602042000200120036a3602000f0b2005412120041011000b0bf6200400418080040ba103636f756c64206e6f742070726f7065726c79206465636f64652073746f7261676520656e7472792f55736572732f7061726974792f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f696e6b5f73746f726167652d332e342e302f7372632f7472616974732f6d6f642e72732700010061000000a20000000a00000073746f7261676520656e7472792077617320656d707479002700010061000000a30000000a0000000900000001000000010000000a0000002f55736572732f7061726974792f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f696e6b5f656e762d332e342e302f7372632f656e67696e652f6f6e5f636861696e2f696d706c732e7273656e636f756e746572656420756e6578706563746564206572726f72380101001c000000d000010068000000f6000000170000002f55736572732f7061726974792f436f64652f3466756e2f666c69707065722f6c69622e727300006c0101002600000008000000050041c483040b716469737061746368696e6720696e6b2120636f6e7374727563746f72206661696c65643a20000000c4010100250000006469737061746368696e6720696e6b21206d657373616765206661696c65643a20000000f4010100210000000900000004000000040000000b0000000c0000000d0041c084040bd11a617474656d707420746f206164642077697468206f766572666c6f7700000000617474656d707420746f206d756c7469706c792077697468206f766572666c6f770000000900000000000000010000000e0000002f55736572732f7061726974792f2e7275737475702f746f6f6c636861696e732f6e696768746c792d616172636836342d6170706c652d64617277696e2f6c69622f727573746c69622f7372632f727573742f6c6962726172792f616c6c6f632f7372632f7261775f7665632e727300940201006f0000008a0100001c0000006361706163697479206f766572666c6f770000001403010011000000940201006f00000006020000050000006120666f726d617474696e6720747261697420696d706c656d656e746174696f6e2072657475726e656420616e206572726f722f55736572732f7061726974792f2e7275737475702f746f6f6c636861696e732f6e696768746c792d616172636836342d6170706c652d64617277696e2f6c69622f727573746c69622f7372632f727573742f6c6962726172792f616c6c6f632f7372632f666d742e72730000730301006b00000064020000200000002f55736572732f7061726974792f2e7275737475702f746f6f6c636861696e732f6e696768746c792d616172636836342d6170706c652d64617277696e2f6c69622f727573746c69622f7372632f727573742f6c6962726172792f616c6c6f632f7372632f7665632f6d6f642e727300f00301006f0000002f0700000d000000f00301006f0000009d07000009000000617474656d707420746f206164642077697468206f766572666c6f7700000000617474656d707420746f2073756274726163742077697468206f766572666c6f77293a00900e010000000000c204010001000000c2040100010000000900000000000000010000000f00000070616e69636b65642061742027272c20f804010001000000f9040100030000003a200000900e0100000000000c05010002000000202020202c0a280a282f55736572732f7061726974792f2e7275737475702f746f6f6c636861696e732f6e696768746c792d616172636836342d6170706c652d64617277696e2f6c69622f727573746c69622f7372632f727573742f6c6962726172792f636f72652f7372632f666d742f6e756d2e727330303031303230333034303530363037303830393130313131323133313431353136313731383139323032313232323332343235323632373238323933303331333233333334333533363337333833393430343134323433343434353436343734383439353035313532353335343535353635373538353936303631363236333634363536363637363836393730373137323733373437353736373737383739383038313832383338343835383638373838383939303931393239333934393539363937393839392f55736572732f7061726974792f2e7275737475702f746f6f6c636861696e732f6e696768746c792d616172636836342d6170706c652d64617277696e2f6c69622f727573746c69622f7372632f727573742f6c6962726172792f636f72652f7372632f666d742f6d6f642e72730000005f0601006e0000005d0500000d0000005f0601006e000000ed050000380000002f55736572732f7061726974792f2e7275737475702f746f6f6c636861696e732f6e696768746c792d616172636836342d6170706c652d64617277696e2f6c69622f727573746c69622f7372632f727573742f6c6962726172792f636f72652f7372632f736c6963652f6d656d6368722e727300f0060100730000004e0000002f000000f0060100730000005a0000001f000000f0060100730000006300000009000000f0060100730000006800000027000000f006010073000000680000003e00000072616e676520737461727420696e64657820206f7574206f662072616e676520666f7220736c696365206f66206c656e67746820b407010012000000c60701002200000072616e676520656e6420696e64657820f807010010000000c6070100220000002f55736572732f7061726974792f2e7275737475702f746f6f6c636861696e732f6e696768746c792d616172636836342d6170706c652d64617277696e2f6c69622f727573746c69622f7372632f727573742f6c6962726172792f636f72652f7372632f736c6963652f697465722e72730000001808010071000000c4050000250000002f55736572732f7061726974792f2e7275737475702f746f6f6c636861696e732f6e696768746c792d616172636836342d6170706c652d64617277696e2f6c69622f727573746c69622f7372632f727573742f6c6962726172792f636f72652f7372632f736c6963652f6d6f642e72739c08010070000000f30300002f0000009c08010070000000d30800001e000000736f7572636520736c696365206c656e67746820282920646f6573206e6f74206d617463682064657374696e6174696f6e20736c696365206c656e67746820282c09010015000000410901002b000000c1040100010000002f55736572732f7061726974792f2e7275737475702f746f6f6c636861696e732f6e696768746c792d616172636836342d6170706c652d64617277696e2f6c69622f727573746c69622f7372632f727573742f6c6962726172792f636f72652f7372632f7374722f636f756e742e7273840901007000000047000000150000008409010070000000540000001100000084090100700000005a00000009000000840901007000000064000000110000008409010070000000660000000d0000002f55736572732f7061726974792f2e7275737475702f746f6f6c636861696e732f6e696768746c792d616172636836342d6170706c652d64617277696e2f6c69622f727573746c69622f7372632f727573742f6c6962726172792f636f72652f7372632f7374722f697465722e727300440a01006f0000009100000011000000440a01006f0000004c0200003c0000002f55736572732f7061726974792f2e7275737475702f746f6f6c636861696e732f6e696768746c792d616172636836342d6170706c652d64617277696e2f6c69622f727573746c69622f7372632f727573742f6c6962726172792f636f72652f7372632f7374722f7472616974732e7273000000d40a010071000000ca000000130000002f55736572732f7061726974792f2e7275737475702f746f6f6c636861696e732f6e696768746c792d616172636836342d6170706c652d64617277696e2f6c69622f727573746c69622f7372632f727573742f6c6962726172792f636f72652f7372632f7374722f7061747465726e2e72730000580b010072000000a101000047000000580b010072000000b401000020000000580b010072000000b401000011000000580b010072000000b8010000260000002f55736572732f7061726974792f2e7275737475702f746f6f6c636861696e732f6e696768746c792d616172636836342d6170706c652d64617277696e2f6c69622f727573746c69622f7372632f727573742f6c6962726172792f636f72652f7372632f697465722f7472616974732f616363756d2e72730c0c0100780000008d00000001000000290501006e000000cd01000005000000617373657274696f6e206661696c65643a206d6964203c3d2073656c662e6c656e28290a900e010000000000c70c0100010000002f55736572732f7061726974792f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f696e6b5f656e762d332e342e302f7372632f656e67696e652f6f6e5f636861696e2f6275666665722e7273000000d80c0100690000005800000009000000d80c0100690000005800000031000000d80c0100690000008b000000210000002f55736572732f7061726974792f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f696e6b5f656e762d332e342e302f7372632f656e67696e652f6f6e5f636861696e2f6578742e72730000740d0100660000008c0100001400000045636473615265636f766572794661696c65644c6f6767696e6744697361626c6564556e6b6e6f776e4e6f7443616c6c61626c65436f64654e6f74466f756e645f456e646f776d656e74546f6f4c6f775472616e736665724661696c65645f42656c6f7753756273697374656e63655468726573686f6c644b65794e6f74466f756e6443616c6c6565526576657274656443616c6c6565547261707065644465636f6465900e0100000000007061696420616e20756e70617961626c65206d657373616765636f756c64206e6f74207265616420696e707574756e61626c6520746f206465636f646520696e707574656e636f756e746572656420756e6b6e6f776e2073656c6563746f72756e61626c6520746f206465636f64652073656c6563746f722f55736572732f7061726974792f2e7275737475702f746f6f6c636861696e732f6e696768746c792d616172636836342d6170706c652d64617277696e2f6c69622f727573746c69622f7372632f727573742f6c6962726172792f636f72652f7372632f736c6963652f696e6465782e72730000100f01007200000081010000470041a09f040bf301617474656d707420746f2073756274726163742077697468206f766572666c6f772f55736572732f7061726974792f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f7061726974792d7363616c652d636f6465632d332e322e312f7372632f636f6465632e7273c10f0100630000007a0000000e0000004572726f72000000000000000100000002000000030000000400000005000000060000000700000008000000090000000c0000000b000000190000001c000000160000001400000019000000f70e0100db0e0100c50e0100b10e0100980e01"},"contract":{"name":"flipper","version":"0.1.0","authors":["[your_name] <[your_email]>"]},"V3":{"spec":{"constructors":[{"args":[{"label":"init_value","type":{"displayName":["bool"],"type":0}}],"docs":["Constructor that initializes the `bool` value to the given `init_value`."],"label":"new","payable":false,"selector":"0x9bae9d5e"},{"args":[],"docs":["Constructor that initializes the `bool` value to `false`.","","Constructors can delegate to other constructors."],"label":"default","payable":false,"selector":"0xed4b9d1b"}],"docs":[],"events":[],"messages":[{"args":[],"docs":[" A message that can be called on instantiated contracts."," This one flips the value of the stored `bool` from `true`"," to `false` and vice versa."],"label":"flip","mutates":true,"payable":false,"returnType":null,"selector":"0x633aa551"},{"args":[],"docs":[" Simply returns the current value of our `bool`."],"label":"get","mutates":false,"payable":false,"returnType":{"displayName":["bool"],"type":0},"selector":"0x2f865bd9"}]},"storage":{"struct":{"fields":[{"layout":{"cell":{"key":"0x0000000000000000000000000000000000000000000000000000000000000000","ty":0}},"name":"value"}]}},"types":[{"id":0,"type":{"def":{"primitive":"bool"}}}]}} \ No newline at end of file +{"source":{"hash":"0xa64fbd08bc40eb972efb18c71ac812bd8219e9fd16b975f9ec070ce96ab32156","language":"ink! 3.4.0","compiler":"rustc 1.68.0-nightly","wasm":"0x0061736d01000000014e0d60037f7f7f017f60027f7f017f60037f7f7f0060027f7f0060057f7f7f7f7f0060047f7f7f7f0060017f0060000060047f7f7f7f017f60017f017e60067f7f7f7f7f7f0060017f017f6000017f02a30107057365616c30127365616c5f64656275675f6d6573736167650001057365616c30107365616c5f7365745f73746f726167650002057365616c30107365616c5f6765745f73746f726167650000057365616c300a7365616c5f696e7075740003057365616c300b7365616c5f72657475726e0002057365616c30167365616c5f76616c75655f7472616e73666572726564000303656e76066d656d6f7279020102100344430002020203000b0302060103030303020c030706070104030201000002010100060703060109040501010104080508040201010204000004050805010101010a01050a040501700110100501000608017f01418080040b071102066465706c6f7900180463616c6c001a0915010041010b0f103738442e2a41422946212324432b0acf5f432b01017f037f2002200346047f200005200020036a200120036a2d00003a0000200341016a21030c010b0b0b950202047f037e230041d0006b22032400200341306a2204200241186a290000370300200341286a2205200241106a290000370300200341206a2206200241086a2900003703002003420137033820032002290000370318200341aea204360240200342808001370244200341106a200341406b220220011008200341186a220120032802102003280214100120032003290318220720032903387c22083703182006200629030022092007200856ad7c22073703002005200529030022082007200954ad7c2207370300200420042903002007200854ad7c37030020034201370338200341aea204360240200342808001370244200341086a20022000100920012003280208200328020c1001200341d0006a24000b5602017f017e230041206b220324002001290200210420034100360218200320043703102002200341106a100d20012003290310370200200341086a20012003280218101520002003290308370300200341206a24000b6202017f017e230041206b220324002001290200210420034100360218200320043703102003200236021c200341106a2003411c6a4104100e20012003290310370200200341086a20012003280218101520002003290308370300200341206a24000b5401027f230041106b220224002002410036020c200020012002410c6a4104100b047f410205200228020c210341022001100c41ff0171220141017120014102461b0b3a000420002003360200200241106a24000b6001047f230041106b22032400200028020422042002492205450440200341086a41002002200028020022061047200120022003280208200328020c41b4a104103a20032002200420061047200020032903003702000b200341106a240020050b4001017f230041106b22012400200141003a000f20002001410f6a4101100b047f4102054101410220012d000f22004101461b410020001b0b200141106a24000b2601017f230041106b22022400200220003a000f20012002410f6a4101100e200241106a24000b6701037f230041106b220324002000280208220420026a2205200449044041909a04411c41cc9b04101e000b200341086a200420052000280200200028020441dc9b0410452003280208200328020c2001200241ec9b04103a20002005360208200341106a24000b5201017f230041206b220124002001410c6a4101360200200141146a4101360200200141a89e04360208200141003602002001410136021c200120003602182001200141186a360210200141b083041011000b910101017f230041306b22022400200241146a41013602002002411c6a4101360200200241a89e043602102002410036020820024102360224200220002d0000410274220041fca1046a28020036022c200220004190a2046a280200360228200141046a28020021002002200241206a3602182002200241286a36022020012802002000200241086a103b200241306a24000b840301037f230041206b22032400200341013a001820032001360214200320003602102003418c8a0436020c200341a89e04360208230041406a220224002002200341086a36020c2002410436022420022002410c6a360220410021004104210402400240024002400240024003402000200441d09a046a2802006a22012000490d0120012100200441086a22044114470d000b4100210041012104024020014110490d002001200120016a22034b200345720d0020034100480d022002200310282003210020022802002204450d060b2002410036021820022004360214200220003602102002410136023c20024102360234200241d09a04360230200241003602282002200241206a360238200241106a200241286a101f0d0241aca2042d000045044041ada2042d00004101710d060b2002280214200228021810004109470d030c040b41f08404411c41e89904101e000b1027000b41f086044133200241286a41b4850441908804101c000b41aca20441013a00000b41ada20441013a00000b000b4801027f230041106b220224002002410036020c024020012002410c6a4104100b450440200228020c21010c010b410121030b2000200136020420002003360200200241106a24000b4701017f230041106b220224002002410036020c024020012002410c6a4104100b4504402000200228020c360001200041003a00000c010b200041013a00000b200241106a24000b0b004100200020011004000b4501017f2002200128020422034b044041ac9a04412341fc9b04101e000b2001200320026b36020420012001280200220120026a36020020002002360204200020013602000b6c02027f027e230041206b22002400200041086a220142003703002000420037030020004110360214200020003602102000411036021c20002000411c6a1005200041106a200028021c10172001290300210220002903002103200041206a2400410541042002200384501b0b3701017f230041106b22022400200241086a410020012000280200200028020441f49c04104520002002290308370200200241106a24000bd40301057f230041306b220024002000027f02400240101641ff0171410546044020004180800136022c200041aea204360228200041286a1019200020002903283703082000200041086a101320002d00000d022000280001220141187621022001411076210320014108762104027f200141ff01712201419b01470440200141ed0147200441ff017141cb004772200341ff0171419d0147720d0441022002411b460d011a0c040b200441ff017141ae0147200341ff0171419d014772200241de0047720d03200041086a100c41ff017122014102460d0320014101710b2101101641ff01712102024002402001410247044020024105460d010c040b20024105470d03200041206a4200370300200041186a4200370300200041106a42003703002000420037030841004100200041086a10070c010b200041206a4200370300200041186a4200370300200041106a42003703002000420037030841002001200041086a10070b200041306a24000f0b200041043a0008200041086a100f000b41040c010b41030b3a0000200041146a41013602002000411c6a4101360200200041888404360210200041003602082000410136022c2000200041286a36021820002000360228200041086a41b083041011000b3301017f230041106b220124002001200028020436020c20002802002001410c6a10032000200128020c1017200141106a24000b9c0d02067f037e230041f0006b22002400024002400240027f02402000027f027f0240101641ff01712201410546044020004180800136025c200041aea204360258200041d8006a101920002000290358370328200041d0006a200041286a1013024020002d00500d002000280051220341187621012003411076210220034108762104024002400240024002400240200341ff0171220341fa016b0e050106060605000b2003411d460d0220034125460d012003412f470440200341e300470440200341b501460d05200341bb0147200441ff017141204772200241ff01712001413a4772720d07410421020c090b200441ff0171413a47200241ff017141a5014772200141d10047720d06410021014100210241000c090b200441ff017141860147200241ff017141db004772200141d90147720d05410121020c070b200441ff0171412c47200241ff017141be014772200141f10047720d04200041086a200041286a100a4102210220002d000c22014102460d04200141017121052000280208220141807e710c070b200441ff017141f90147200241ff017141a60147722001410947720d03200041106a200041286a100a20002d001422014102460d0320014101712105410321022000280210220141807e710c060b200441ff0171413247200241ff017141e10047722001419f0147720d02410521020c040b200441ff017141d70147200241ff017141b4014772200141f00147720d01410621020c030b200441ff017141db0047200241ff017141d8014772200141ea0147720d00200041186a200041286a101220002802180d0041072102200028021c220141807e710c030b41030c030b200020013a0028200041286a100f000b4100210141000b2104200041306a4200370300200041386a4200370300200041406b42003703002000420037032820004201370348200041808001360254200041aea204360250024002400240200041286a200041d0006a101b0e0400060601060b20002000290350370358200041d8006a100c41ff017122034102460d06200029034821062000420137034820002006200029032822077c22063703282000200029033022082006200754ad7c22063703302000200029033822072006200854ad7c2206370338200020002903402006200754ad7c370340200041808001360254200041aea2043602500240200041286a200041d0006a101b0e0400060601060b200020002903503703582000200041d8006a10122000280200450d010c060b230041106b220124002001411736020c200141988104360208230041206b220024002000410c6a4101360200200041146a4101360200200041a89e04360208200041003602002000410236021c2000200141086a3602182000200041186a360210200041b081041011000b200141ff01712004722104200028020421012000200341004722033a002420002001360220024002400240024002400240024002400240200241016b0e0706050504030200010b101641ff01714105470d07200041206a2004101d0c090b101641ff01714105460d050c060b101641ff01714105470d05200041206a417f101d0c070b101641ff01714105470d04200041206a4101101d0c060b101641ff01714105470d03230041206b22002400200041aea204360210200042808001370214200041086a200041106a200110090c090b101641ff01714105470d02230041206b22012400200141aea204360210200142808001370214230041206b22002400200141106a2202290200210620004100360218200020063703102000200436021c200041106a22042000411c6a4104100e20052004100d20022000290310370200200041086a200220002802181015200141086a2000290308370300200041206a24002001280208200128020c1014000b101641ff01714105470d01230041206b22002400200041aea204360210200042808001370214200041086a200041106a200310080c070b2003450c030b41040b3a0050200041346a41013602002000413c6a4101360200200041b48404360230200041003602282000410136025c2000200041d8006a3602382000200041d0006a360258200041286a41b083041011000b2000280220210120002d00240b21022001200241ff017141004741c083041007200041f0006a24000f0b200041e4006a4101360200200041ec006a4100360200200041f08204360260200041a89e0436026820004100360258200041d8006a41f882041011000b200041003a0058418080044127200041d8006a41dc810441888104101c000b2000280208200028020c1014000b5401017f230041106b220224002002200128020436020c200020012802002002410c6a100221002001200228020c1017410c21012000410b4d0440200041027441cca1046a28020021010b200241106a240020010b860101017f230041406a220524002005200136020c200520003602082005200336021420052002360210200541246a41023602002005412c6a41023602002005413c6a4103360200200541c08a0436022020054100360218200541023602342005200541306a3602282005200541106a3602382005200541086a360230200541186a20041011000b3201017f20014100482001200028020022016a220220014873450440200020023602000f0b41c08104411c41bc8404101e000b5001017f230041206b220324002003410c6a4101360200200341146a4100360200200341a89e04360210200341003602002003200136021c200320003602182003200341186a360208200320021011000b5501017f230041206b2202240020022000360204200241186a200141106a290200370300200241106a200141086a29020037030020022001290200370308200241046a41cc8404200241086a1020200241206a24000bee0301057f230041406a22032400200341033a003820034280808080800437033020034100360228200341003602202003200136021c20032000360218027f0240024020022802002201450440200241146a28020022004103742105200041ffffffff017121072002280210210441002101034020012005460d02200228020820016a220041046a28020022060440200328021820002802002006200328021c28020c1100000d040b200141086a2101200428020020042802042106200441086a2104200341186a2006110100450d000b0c020b200228020422074105742100200741ffffff3f71210703402000450d01200228020820046a220541046a28020022060440200328021820052802002006200328021c28020c1100000d030b20032001411c6a2d00003a00382003200141146a290200370330200341106a200228021022052001410c6a103920032003290310370320200341086a2005200141046a103920032003290308370328200441086a2104200041206b210020012802002106200141206a2101200520064103746a2205280200200341186a2005280204110100450d000b0c010b2002410c6a28020020074b04402003280218200228020820074103746a22002802002000280204200328021c28020c1100000d010b41000c010b41010b200341406b24000b0f00200028020020012002102241000b5801017f20022000280200200028020822036b4b044020002003200210251026200028020821030b200028020420036a2001200210061a2003200220036a22014b044041f08404411c41a08904101e000b200020013602080bbe0201027f230041106b220224000240024002400240200028020022002002410c6a027f0240024020014180014f04402002410036020c2001418010490d012001418080044f0d0220022001413f71418001723a000e20022001410c7641e001723a000c20022001410676413f71418001723a000d41030c030b200028020822032000280200460d030c040b20022001413f71418001723a000d2002200141067641c001723a000c41020c010b20022001413f71418001723a000f20022001410676413f71418001723a000e20022001410c76413f71418001723a000d2002200141127641077141f001723a000c41040b10220c020b20002003410110251026200028020821030b200028020420036a20013a0000200341016a2201450d01200020013602080b200241106a240041000f0b41f08404411c41908904101e000b4a01017f230041206b220224002000280200200241186a200141106a290200370300200241106a200141086a29020037030020022001290200370308200241086a101f200241206a24000b990401067f230041206b220324000240027f41002001200120026a22014b0d001a2000280200220220026a22052002490d012005200120012005491b22014108200141084b1b2201417f73411f7621040240200204402003410136021820032002360214200320002802043602100c010b200341003602180b200341106a2106230041106b220524002003027f0240027f0240200404400240200141004e044020062802080d012005200110282005280204210220052802000c040b0c040b20062802042208450440200541086a20011028200528020c210220052802080c030b20012102410041a4a204280200220420016a22072004490d021a2006280200210641a8a2042802002007490440200141ffff036a220741107640002202417f46200241ffff0371200247720d022002411074220420074180807c716a22022004490d0241a8a2042002360200200121024100200120046a22072004490d031a0b41a4a204200736020041002004450d021a20042006200810060c020b200320013602040c020b2001210241000b2204044020032004360204200341086a200236020041000c020b20032001360204200341086a410136020041010c010b200341086a410036020041010b360200200541106a240020032802004504402003280204210220002001360200200020023602044181808080780c010b200341086a2802000b200341206a24000f0b41908504412141b48604101e000b1b00024020004181808080784704402000450d01000b0f0b1027000b4601017f230041206b22002400200041146a41013602002000411c6a4100360200200041d88604360210200041a89e0436021820004100360208200041086a41e086041011000ba10101027f027f410041a4a204280200220320016a22022003490d001a024041a8a2042802002002490440200141ffff036a22022001490d012002411076220240002203417f46200341ffff0371200347720d012003411074220320024110746a22022003490d0141a8a20420023602004100200120036a22022003490d021a0b41a4a204200236020020030c010b41000b210220002001360204200020023602000b0300010b0e0020002802001a03400c000b000b0d004294d3af9489a8cbd9ed000bb20101017f230041106b2205240020022003490440230041306b220024002000200236020420002003360200200041146a41023602002000411c6a41023602002000412c6a410536020020004198900436021020004100360208200041053602242000200041206a3602182000200041046a36022820002000360220200041086a20041011000b200541086a200320022001102d200528020c21012000200528020836020020002001360204200541106a24000b14002000200120022003419ca00441d0890410480bd806020b7f027e230041406a2203240020002802002202ad210d0240024002400240024002400240024020024190ce004f044041272100200d210e0240034020004104490d01200341196a20006a220241046b200e200e4290ce0080220d4290ce007e7da7220441ffff037141e4006e220641017441c78b046a2f00003b0000200241026b2004200641e4006c6b41ffff037141017441c78b046a2f00003b0000200041046b2100200e42ffc1d72f56200d210e0d000b200da7220241e3004d0d0320004102490d090c020b0c080b41272100200241e3004b0d002002410a490d040c020b200041026b2200200341196a6a200da72202200241ffff037141e4006e220241e4006c6b41ffff037141017441c78b046a2f00003b00000b2002410a490d01200041024f0d000c050b200041026b2200200341196a6a200241017441c78b046a2f00003b00000c020b2000450d030b200041016b2200200341196a6a200241306a3a00000b200041274b0d01412820006b412720006b22062001280218220541017122071b2102410021042005410471044041a89e042104200241a89e0441a89e04102f20026a22024b0d010b412b418080c40020071b2107200341196a20006a2108024020012802084504404101210020012802002202200141046a28020022012007200410320d01200220082006200128020c11000021000c010b024020022001410c6a28020022094904402005410871450d01200128021c210b2001413036021c20012d0020210c41012100200141013a002020012802002205200141046a280200220a2007200410320d02200341106a2001200920026b4101103320032802142202418080c400460d022003280210200520082006200a28020c1100000d0220022005200a10340d022001200c3a00202001200b36021c410021000c020b4101210020012802002202200141046a28020022012007200410320d01200220082006200128020c11000021000c010b41012100200341086a2001200920026b41011033200328020c2205418080c400460d00200328020820012802002202200141046a28020022012007200410320d00200220082006200128020c1100000d00200520022001103421000b200341406b240020000f0b41b08904411c41808e04101e000b41d08904412141f89904101e000ba704010a7f230041106b2203240002400240200020016b22024110490d002002200141036a417c7120016b220049200041044b720d00200220006b22044104490d002001200010302206200020016a22082004417c716a200441037110306a220220064f0440200441027621050240024003402005450d05200320082005200541c001200541c001491b41f091041031200328020c21052003280208210820032003280200200328020422002000417c7141f092041031200328020c210920032802082107024020032802042200450440410021010c010b2003280200220420004102746a210a4100210103402004220641106a2104410021000240034020012001200020066a280200220b417f73410776200b410676724181828408716a22014d0440200041046a22004110470d010c020b0b41b08904411c41e89404101e000b2004200a470d000b0b20022002200141087641ff81fc0771200141ff81fc07716a418180046c4110766a22024b0d012009450d000b200941027421004100210103402001200120072802002204417f734107762004410676724181828408716a22014b0d02200741046a2107200041046b22000d000b20022002200141087641ff81fc0771200141ff81fc07716a418180046c4110766a22024d0d0441b08904411c41989504101e000b41b08904411c41f89404101e000b41b08904411c41889504101e000b41b08904411c41d89404101e000b20012002103021020b200341106a240020020b4601017f200145044041000f0b024003402002200220002c000041bf7f4a6a22024b0d01200041016a2100200141016b22010d000b20020f0b41b08904411c41e89904101e000b3e00200220034f044020002003360204200020013602002000410c6a200220036b3602002000200120034102746a3602080f0b41ac9a0441232004101e000b39000240027f2002418080c40047044041012000200220012802101101000d011a0b20030d0141000b0f0b200020034100200128020c1100000bae0101027f20022104024002400240200320012d0020220320034103461b41ff0171220341016b0e03010001020b200241016a2203044020034101762104200241017621030c020b41b08904411c41908e04101e000b41002104200221030b200341016a2102200128021c2103200128020421052001280200210102400340200241016b2202450d01200120032005280210110100450d000b418080c40021030b20002003360204200020043602000b3201017f027f0340200020002004460d011a200441016a2104200220012003280210110100450d000b200441016b0b2000490b4b01017f230041106b22052400200120034d0440200541086a410020012002102d200528020c21012000200528020836020020002001360204200541106a24000f0b2001200320041036000b7501017f230041306b220324002003200136020420032000360200200341146a41023602002003411c6a41023602002003412c6a4105360200200341b8900436021020034100360208200341053602242003200341206a3602182003200341046a36022820032003360220200341086a20021011000bea04010b7f230041106b2209240020002802042104200028020021030240024002402001280208220b410147200128021022024101477145044020024101470d02200320046a210c200141146a28020041016a210a410021022003210003402000200c460d03027f024020002c0000220641004e0440200041016a2105200641ff017121070c010b20002d0001413f7121052006411f7121072006415f4d044020074106742005722107200041026a21050c010b20002d0002413f7120054106747221082006417049044020082007410c74722107200041036a21050c010b200041046a210520022106418080c4002007411274418080f0007120002d0003413f71200841067472722207418080c400460d011a0b2002200520006b6a22062002490d0320070b2108200a41016b220a044020052100200621022008418080c400470d010c040b0b2008418080c400460d02024002402002450d00200220044f04404100210020022004460d010c020b41002100200220036a2c00004140480d010b200321000b2002200420001b21042000200320001b21030c020b200128020020032004200128020428020c11000021000c020b41b08904411c41989604101e000b200b450440200128020020032004200128020428020c11000021000c010b2001410c6a2802002200200320046a2003102f22024b0440200941086a2001200020026b4100103341012100200928020c2202418080c400460d0120092802082001280200220520032004200141046a280200220128020c1100000d01200220052001103421000c010b200128020020032004200128020428020c11000021000b200941106a240020000b140020002802002001200028020428020c1101000b5501027f0240027f02400240200228020041016b0e020103000b200241046a0c010b200120022802044103746a22012802044106470d0120012802000b2802002104410121030b20002004360204200020033602000b8501002001200346044020002002200110061a0f0b230041306b220024002000200336020420002001360200200041146a41033602002000411c6a41023602002000412c6a4105360200200041d0930436021020004100360208200041053602242000200041206a360218200020003602282000200041046a360220200041086a20041011000b4901017f230041206b22032400200341186a200241106a290200370300200341106a200241086a2902003703002003200229020037030820002001200341086a1020200341206a24000bda08010b7f23004190016b22032400200341003b0184012003410a3602800120034281808080a00137037820032002360274200341003602702003200236026c200320013602682003200236026420034100360260200028020421062000280200210720002802082108200341fc006a2109027f0340024002400240024020032d008501450440200341d8006a2003280268220c200328026c20032802702003280274103d0240024020032802582201450d00200328025c2100034002400240024002400240027f0240024002400240200328027822020440200220096a41016b2d00002104200041084f04402001200141036a417c712202460440200041086b210a410021020c040b200341d0006a200220016b22022000200020024b1b22022001200041948f041035200341c8006a200420032802502003280254103e20032802484101470d02200328024c21010c050b200341306a200420012000103e2003280234210120032802300c050b41d08904412141b09804101e000b2002200041086b220a4b0d010b200441818284086c210b0340200241046a22052002490d04200120026a280200200b73220d417f73200d41818284086b71200120056a280200200b732205417f73200541818284086b7172418081828478710d012002200241086a22024b0d072002200a4d0d000b0b200341406b20012000200241c48f04102c200341386a200420032802402003280244103e410020032802384101470d011a2002200328023c6a220120024f0d0041b08904411c41d48f04101e000b41010b4101460440200141016a2200450d022000200328027022006a22022000490d0320032002360270200220032802782200490d05200341286a2003280268200328026c200220006b2002103d20032802282202450d05200328022c2100200341206a20032802782009410441e0980410352002200020032802202003280224103f450d05200341186a200328026020032802702200200c104020032000360260200328021c2102200328021821000c080b200320032802743602700c060b41b08904411c41a48f04101e000b41b08904411c41c09804101e000b41b08904411c41d09804101e000b41b08904411c41b48f04101e000b200341106a2003280268200328026c20032802702003280274103d20032802142100200328021022010d000b0b4100210020032d0085010d00024020032d008401044020032802642101200328026021040c010b2003280264220120032802602204490d0420012004460d010b200341013a008501200341086a2004200120032802681040200328020c2102200328020821000b20000d010b41000c050b20082d0000450d01200741d08a044104200628020c110000450d010c020b41d08904412141a89604101e000b2003410a36028c0120082002047f200320002002200241016b41809304102c2003418c016a410120032802002003280204103f0541000b3a0000200720002002200628020c110000450d010b0b41010b20034190016a24000b4c01037f230041106b220524002002200449200320044b72450440200541086a200320042001102d200528020c2107200528020821060b2000200736020420002006360200200541106a24000b5701027f024002402003450440410021030c010b200141ff017121054101210103402005200220046a2d0000460440200421030c030b2003200441016a2204470d000b0b410021010b20002003360204200020013602000b4d01017f2001200346047f027f034041002001450d011a200141016b210120022d0000210320002d00002104200041016a2100200241016a210220032004460d000b200420036b0b0541010b450b1400200020012002200341ac970441d0890410480b5801027f230041206b22022400200128020421032001280200200241186a2000280200220041106a290200370300200241106a200041086a290200370300200220002902003703082003200241086a1020200241206a24000b0b002000280200200110370b1800200128020041c4a1044105200128020428020c1100000b990301037f230041406a220224002000280200210341012100024020012802002204419c8a04410c200141046a280200220128020c1100000d0002402003280208220004402002200036020c200241346a4102360200410121002002413c6a4101360200200241ac8a0436023020024100360228200241073602142002200241106a36023820022002410c6a36021020042001200241286a103b450d010c020b20032802002200200328020428020c11090042c8b5e0cfca86dbd3897f520d002002200036020c200241346a4102360200410121002002413c6a4101360200200241ac8a0436023020024100360228200241083602142002200241106a36023820022002410c6a36021020042001200241286a103b0d010b200328020c21002002411c6a4103360200200241246a41033602002002413c6a4105360200200241346a4105360200200241f489043602182002410036021020022000410c6a3602382002200041086a3602302002410236022c200220003602282002200241286a36022020042001200241106a103b21000b200241406b240020000ba201000240200120024d0440200220044d0d012002200420051036000b230041306b220024002000200236020420002001360200200041146a41023602002000411c6a41023602002000412c6a4105360200200041ec900436021020004100360208200041053602242000200041206a3602182000200041046a36022820002000360220200041086a20051011000b2000200220016b3602042000200120036a3602000b980401047f230041106b22022400024002400240024002400240024002400240024002400240024020002d000041016b0e0b0102030405060708090a0b000b410121002001280200220341a29e0441062001280204220528020c22041100000d0b024020012d0018410471450440200341d88a04410120041100000d0d200341c4a10441052004110000450d010c0d0b200341d68a04410220041100000d0c2002200536020420022003360200200241013a000f20022002410f6a360208200241c4a1044105103c0d0c200241d48a044102103c0d0c0b200341f189044101200411000021000c0b0b200128020041959e04410d200128020428020c11000021000c0a0b200128020041879e04410e200128020428020c11000021000c090b200128020041fc9d04410b200128020428020c11000021000c080b200128020041e29d04411a200128020428020c11000021000c070b200128020041d49d04410e200128020428020c11000021000c060b200128020041c49d044110200128020428020c11000021000c050b200128020041b89d04410c200128020428020c11000021000c040b200128020041ad9d04410b200128020428020c11000021000c030b200128020041a69d044107200128020428020c11000021000c020b200128020041979d04410f200128020428020c11000021000c010b200128020041849d044113200128020428020c11000021000b200241106a240020000b14002000200120022003419ca00441b0a00410480b2800200120024d04402000200220016b3602042000200120036a3602000f0b200541212004101e000b0b87220400418080040bbd03636f756c64206e6f742070726f7065726c79206465636f64652073746f7261676520656e7472792f55736572732f7061726974792f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f696e6b5f73746f726167652d332e342e302f7372632f7472616974732f6d6f642e72732700010061000000a20000000a00000073746f7261676520656e7472792077617320656d707479002700010061000000a30000000a000000617474656d707420746f206164642077697468206f766572666c6f770900000001000000010000000a0000002f55736572732f7061726974792f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f696e6b5f656e762d332e342e302f7372632f656e67696e652f6f6e5f636861696e2f696d706c732e7273656e636f756e746572656420756e6578706563746564206572726f72540101001c000000ec00010068000000f6000000170000002f55736572732f7061726974792f436f64652f3466756e2f666c69707065722f6c69622e72730000880101002600000008000000050041e083040b81016469737061746368696e6720696e6b2120636f6e7374727563746f72206661696c65643a20000000e0010100250000006469737061746368696e6720696e6b21206d657373616765206661696c65643a20000000100201002100000088010100260000005b0000000d0000000900000004000000040000000b0000000c0000000d0041f084040b9515617474656d707420746f206164642077697468206f766572666c6f7700000000617474656d707420746f206d756c7469706c792077697468206f766572666c6f770000000900000000000000010000000e0000002f55736572732f7061726974792f2e7275737475702f746f6f6c636861696e732f6e696768746c792d616172636836342d6170706c652d64617277696e2f6c69622f727573746c69622f7372632f727573742f6c6962726172792f616c6c6f632f7372632f7261775f7665632e727300c40201006f0000008a0100001c0000006361706163697479206f766572666c6f770000004403010011000000c40201006f00000006020000050000006120666f726d617474696e6720747261697420696d706c656d656e746174696f6e2072657475726e656420616e206572726f722f55736572732f7061726974792f2e7275737475702f746f6f6c636861696e732f6e696768746c792d616172636836342d6170706c652d64617277696e2f6c69622f727573746c69622f7372632f727573742f6c6962726172792f616c6c6f632f7372632f666d742e72730000a30301006b00000064020000200000002f55736572732f7061726974792f2e7275737475702f746f6f6c636861696e732f6e696768746c792d616172636836342d6170706c652d64617277696e2f6c69622f727573746c69622f7372632f727573742f6c6962726172792f616c6c6f632f7372632f7665632f6d6f642e727300200401006f000000300700000d000000200401006f0000009e07000009000000617474656d707420746f206164642077697468206f766572666c6f7700000000617474656d707420746f2073756274726163742077697468206f766572666c6f77293a00280f010000000000f204010001000000f2040100010000000900000000000000010000000f00000070616e69636b65642061742027272c20280501000100000029050100030000003a200000280f0100000000003c05010002000000202020202c0a280a282f55736572732f7061726974792f2e7275737475702f746f6f6c636861696e732f6e696768746c792d616172636836342d6170706c652d64617277696e2f6c69622f727573746c69622f7372632f727573742f6c6962726172792f636f72652f7372632f666d742f6e756d2e727330303031303230333034303530363037303830393130313131323133313431353136313731383139323032313232323332343235323632373238323933303331333233333334333533363337333833393430343134323433343434353436343734383439353035313532353335343535353635373538353936303631363236333634363536363637363836393730373137323733373437353736373737383739383038313832383338343835383638373838383939303931393239333934393539363937393839392f55736572732f7061726974792f2e7275737475702f746f6f6c636861696e732f6e696768746c792d616172636836342d6170706c652d64617277696e2f6c69622f727573746c69622f7372632f727573742f6c6962726172792f636f72652f7372632f666d742f6d6f642e72730000008f0601006e0000005d0500000d0000008f0601006e000000ed050000380000002f55736572732f7061726974792f2e7275737475702f746f6f6c636861696e732f6e696768746c792d616172636836342d6170706c652d64617277696e2f6c69622f727573746c69622f7372632f727573742f6c6962726172792f636f72652f7372632f736c6963652f6d656d6368722e72730020070100730000004e0000002f00000020070100730000005a0000001f00000020070100730000006300000009000000200701007300000068000000270000002007010073000000680000003e00000072616e676520737461727420696e64657820206f7574206f662072616e676520666f7220736c696365206f66206c656e67746820e407010012000000f60701002200000072616e676520656e6420696e646578202808010010000000f607010022000000736c69636520696e64657820737461727473206174202062757420656e6473206174200048080100160000005e0801000d0000002f55736572732f7061726974792f2e7275737475702f746f6f6c636861696e732f6e696768746c792d616172636836342d6170706c652d64617277696e2f6c69622f727573746c69622f7372632f727573742f6c6962726172792f636f72652f7372632f736c6963652f697465722e72730000007c08010071000000c4050000250000002f55736572732f7061726974792f2e7275737475702f746f6f6c636861696e732f6e696768746c792d616172636836342d6170706c652d64617277696e2f6c69622f727573746c69622f7372632f727573742f6c6962726172792f636f72652f7372632f736c6963652f6d6f642e72730009010070000000f30300002f0000000009010070000000d30800001e000000736f7572636520736c696365206c656e67746820282920646f6573206e6f74206d617463682064657374696e6174696f6e20736c696365206c656e67746820289009010015000000a50901002b000000f1040100010000002f55736572732f7061726974792f2e7275737475702f746f6f6c636861696e732f6e696768746c792d616172636836342d6170706c652d64617277696e2f6c69622f727573746c69622f7372632f727573742f6c6962726172792f636f72652f7372632f7374722f636f756e742e7273e8090100700000004700000015000000e8090100700000005400000011000000e8090100700000005a00000009000000e8090100700000006400000011000000e809010070000000660000000d0000002f55736572732f7061726974792f2e7275737475702f746f6f6c636861696e732f6e696768746c792d616172636836342d6170706c652d64617277696e2f6c69622f727573746c69622f7372632f727573742f6c6962726172792f636f72652f7372632f7374722f697465722e727300a80a01006f0000009100000011000000a80a01006f0000004c0200003c0000002f55736572732f7061726974792f2e7275737475702f746f6f6c636861696e732f6e696768746c792d616172636836342d6170706c652d64617277696e2f6c69622f727573746c69622f7372632f727573742f6c6962726172792f636f72652f7372632f7374722f7472616974732e7273000000380b010071000000ca000000130000002f55736572732f7061726974792f2e7275737475702f746f6f6c636861696e732f6e696768746c792d616172636836342d6170706c652d64617277696e2f6c69622f727573746c69622f7372632f727573742f6c6962726172792f636f72652f7372632f7374722f7061747465726e2e72730000bc0b010072000000a101000047000000bc0b010072000000b401000020000000bc0b010072000000b401000011000000bc0b010072000000b8010000260000002f55736572732f7061726974792f2e7275737475702f746f6f6c636861696e732f6e696768746c792d616172636836342d6170706c652d64617277696e2f6c69622f727573746c69622f7372632f727573742f6c6962726172792f636f72652f7372632f697465722f7472616974732f616363756d2e7273700c0100780000009500000001000000590501006e000000cd010000050041909a040b9308617474656d707420746f206164642077697468206f766572666c6f77617373657274696f6e206661696c65643a206d6964203c3d2073656c662e6c656e28290a280f0100000000004f0d0100010000002f55736572732f7061726974792f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f696e6b5f656e762d332e342e302f7372632f656e67696e652f6f6e5f636861696e2f6275666665722e7273000000600d010069000000580000001c000000600d0100690000005800000009000000600d0100690000005800000031000000600d0100690000008b000000210000002f55736572732f7061726974792f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f696e6b5f656e762d332e342e302f7372632f656e67696e652f6f6e5f636861696e2f6578742e727300000c0e0100660000008c0100001400000045636473615265636f766572794661696c65644c6f6767696e6744697361626c6564556e6b6e6f776e4e6f7443616c6c61626c65436f64654e6f74466f756e645f456e646f776d656e74546f6f4c6f775472616e736665724661696c65645f42656c6f7753756273697374656e63655468726573686f6c644b65794e6f74466f756e6443616c6c6565526576657274656443616c6c6565547261707065644465636f6465280f0100000000007061696420616e20756e70617961626c65206d657373616765636f756c64206e6f74207265616420696e707574756e61626c6520746f206465636f646520696e707574656e636f756e746572656420756e6b6e6f776e2073656c6563746f72756e61626c6520746f206465636f64652073656c6563746f722f55736572732f7061726974792f2e7275737475702f746f6f6c636861696e732f6e696768746c792d616172636836342d6170706c652d64617277696e2f6c69622f727573746c69622f7372632f727573742f6c6962726172792f636f72652f7372632f736c6963652f696e6465782e72730000a80f010072000000820100004700000000000000617474656d707420746f2073756274726163742077697468206f766572666c6f772f55736572732f7061726974792f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f7061726974792d7363616c652d636f6465632d332e322e312f7372632f636f6465632e727351100100630000007a0000000e0000004572726f72000000000000000100000002000000030000000400000005000000060000000700000008000000090000000c0000000b000000190000001c0000001600000014000000190000008f0f0100730f01005d0f0100490f0100300f01"},"contract":{"name":"flipper","version":"0.1.0","authors":["[your_name] <[your_email]>"]},"V3":{"spec":{"constructors":[{"args":[{"label":"init_value","type":{"displayName":["bool"],"type":0}}],"docs":["Constructor that initializes the `bool` value to the given `init_value`."],"label":"new","payable":false,"selector":"0x9bae9d5e"},{"args":[],"docs":["Constructor that initializes the `bool` value to `false`.","","Constructors can delegate to other constructors."],"label":"default","payable":false,"selector":"0xed4b9d1b"}],"docs":[],"events":[],"messages":[{"args":[],"docs":[" A message that can be called on instantiated contracts."," This one flips the value of the stored `bool` from `true`"," to `false` and vice versa."],"label":"flip","mutates":true,"payable":false,"returnType":null,"selector":"0x633aa551"},{"args":[],"docs":[" Simply returns the current value of our `bool`."],"label":"get","mutates":false,"payable":false,"returnType":{"displayName":["bool"],"type":0},"selector":"0x2f865bd9"},{"args":[{"label":"a","type":{"displayName":["u32"],"type":2}},{"label":"b","type":{"displayName":["bool"],"type":0}}],"docs":[" multiple arg method1."],"label":"m1","mutates":false,"payable":false,"returnType":{"displayName":[],"type":3},"selector":"0xfa2cbe71"},{"args":[{"label":"a","type":{"displayName":["u32"],"type":2}},{"label":"b","type":{"displayName":["bool"],"type":0}}],"docs":[" multiple arg method2."],"label":"m2","mutates":false,"payable":false,"returnType":{"displayName":["M2"],"type":4},"selector":"0x25f9a609"},{"args":[],"docs":[" get the current count."],"label":"get_count","mutates":false,"payable":false,"returnType":{"displayName":["i32"],"type":1},"selector":"0xbb20003a"},{"args":[],"docs":[" increment current count by 1"],"label":"inc","mutates":true,"payable":false,"returnType":null,"selector":"0x1d32619f"},{"args":[],"docs":[" decrement current count by 1"],"label":"dec","mutates":true,"payable":false,"returnType":null,"selector":"0xb5d7b4f0"},{"args":[{"label":"n","type":{"displayName":["i32"],"type":1}}],"docs":[" increment current count by n"],"label":"inc_by","mutates":true,"payable":false,"returnType":null,"selector":"0xfe5bd8ea"}]},"storage":{"struct":{"fields":[{"layout":{"cell":{"key":"0x0000000000000000000000000000000000000000000000000000000000000000","ty":0}},"name":"value"},{"layout":{"cell":{"key":"0x0100000000000000000000000000000000000000000000000000000000000000","ty":1}},"name":"count"}]}},"types":[{"id":0,"type":{"def":{"primitive":"bool"}}},{"id":1,"type":{"def":{"primitive":"i32"}}},{"id":2,"type":{"def":{"primitive":"u32"}}},{"id":3,"type":{"def":{"tuple":[2,0]}}},{"id":4,"type":{"def":{"composite":{"fields":[{"name":"a","type":2,"typeName":"u32"},{"name":"b","type":0,"typeName":"bool"}]}},"path":["flipper","flipper","M2"]}}]}} \ No newline at end of file diff --git a/examples/smart_contract/flipper.wasm b/examples/smart_contract/flipper.wasm index fa0674ef762a74dcc1a410cb5436d33628ef7de7..592ae8515270a3b382919338848f2a06b58934d9 100644 GIT binary patch delta 5726 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 delta 4055 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 diff --git a/examples/smart_contract/metadata.json b/examples/smart_contract/metadata.json index 7060a8834..b3d0b6ac3 100644 --- a/examples/smart_contract/metadata.json +++ b/examples/smart_contract/metadata.json @@ -1,8 +1,8 @@ { "source": { - "hash": "0x2345709e061bfa0d374eaf0c25f19c8dce43ac11362c55196e1ecf465781b750", + "hash": "0xa64fbd08bc40eb972efb18c71ac812bd8219e9fd16b975f9ec070ce96ab32156", "language": "ink! 3.4.0", - "compiler": "rustc 1.67.0-nightly" + "compiler": "rustc 1.68.0-nightly" }, "contract": { "name": "flipper", @@ -76,6 +76,133 @@ "type": 0 }, "selector": "0x2f865bd9" + }, + { + "args": [ + { + "label": "a", + "type": { + "displayName": [ + "u32" + ], + "type": 2 + } + }, + { + "label": "b", + "type": { + "displayName": [ + "bool" + ], + "type": 0 + } + } + ], + "docs": [ + " multiple arg method1." + ], + "label": "m1", + "mutates": false, + "payable": false, + "returnType": { + "displayName": [], + "type": 3 + }, + "selector": "0xfa2cbe71" + }, + { + "args": [ + { + "label": "a", + "type": { + "displayName": [ + "u32" + ], + "type": 2 + } + }, + { + "label": "b", + "type": { + "displayName": [ + "bool" + ], + "type": 0 + } + } + ], + "docs": [ + " multiple arg method2." + ], + "label": "m2", + "mutates": false, + "payable": false, + "returnType": { + "displayName": [ + "M2" + ], + "type": 4 + }, + "selector": "0x25f9a609" + }, + { + "args": [], + "docs": [ + " get the current count." + ], + "label": "get_count", + "mutates": false, + "payable": false, + "returnType": { + "displayName": [ + "i32" + ], + "type": 1 + }, + "selector": "0xbb20003a" + }, + { + "args": [], + "docs": [ + " increment current count by 1" + ], + "label": "inc", + "mutates": true, + "payable": false, + "returnType": null, + "selector": "0x1d32619f" + }, + { + "args": [], + "docs": [ + " decrement current count by 1" + ], + "label": "dec", + "mutates": true, + "payable": false, + "returnType": null, + "selector": "0xb5d7b4f0" + }, + { + "args": [ + { + "label": "n", + "type": { + "displayName": [ + "i32" + ], + "type": 1 + } + } + ], + "docs": [ + " increment current count by n" + ], + "label": "inc_by", + "mutates": true, + "payable": false, + "returnType": null, + "selector": "0xfe5bd8ea" } ] }, @@ -90,6 +217,15 @@ } }, "name": "value" + }, + { + "layout": { + "cell": { + "key": "0x0100000000000000000000000000000000000000000000000000000000000000", + "ty": 1 + } + }, + "name": "count" } ] } @@ -102,6 +238,59 @@ "primitive": "bool" } } + }, + { + "id": 1, + "type": { + "def": { + "primitive": "i32" + } + } + }, + { + "id": 2, + "type": { + "def": { + "primitive": "u32" + } + } + }, + { + "id": 3, + "type": { + "def": { + "tuple": [ + 2, + 0 + ] + } + } + }, + { + "id": 4, + "type": { + "def": { + "composite": { + "fields": [ + { + "name": "a", + "type": 2, + "typeName": "u32" + }, + { + "name": "b", + "type": 0, + "typeName": "bool" + } + ] + } + }, + "path": [ + "flipper", + "flipper", + "M2" + ] + } } ] } From c48c6fee2b3a1a5a6525845cc17254c015e48e5d Mon Sep 17 00:00:00 2001 From: Matias Volpe Date: Thu, 15 Dec 2022 12:37:29 -0300 Subject: [PATCH 10/21] feat: add contract event decoding --- examples/smart_contract.ts | 87 ++++++++++---- examples/smart_contract/flipper.contract | 2 +- examples/smart_contract/flipper.wasm | Bin 16990 -> 18680 bytes examples/smart_contract/metadata.json | 141 +++++++++++++++++++++-- 4 files changed, 198 insertions(+), 32 deletions(-) diff --git a/examples/smart_contract.ts b/examples/smart_contract.ts index df0bc6747..757a53cbd 100644 --- a/examples/smart_contract.ts +++ b/examples/smart_contract.ts @@ -18,23 +18,22 @@ const contract = await getContract( getFilePath("smart_contract/metadata.json"), ) -const contractAddress = U.throwIfError(await instantiateContractTx().run()) -console.log("Deployed Contract address", U.ss58.encode(42, contractAddress)) +const ss58Prefix = C.const(client)("System", "SS58Prefix").access("value") function instantiateContractTx() { const constructor = findContractConstructorByLabel("default")! const salt = Uint8Array.from(Array.from([0, 0, 0, 0]), () => Math.floor(Math.random() * 16)) - const value = preSubmitContractInstantiateDryRunGasEstimate(constructor, contract.wasm, salt) - .next(({ gasRequired, result: { accountId } }) => { + const value = C.Z.ls( + preSubmitContractInstantiateDryRunGasEstimate(constructor, contract.wasm, salt), + ss58Prefix, + ) + .next(([{ gasRequired, result: { accountId } }, prefix]) => { // the contract address derived from the code hash and the salt - console.log("Derived contract address", U.ss58.encode(42, accountId)) + console.log("Derived contract address", U.ss58.encode(prefix, accountId)) return { type: "instantiateWithCode", value: 0n, - gasLimit: { - refTime: gasRequired.refTime, - proofSize: gasRequired.proofSize, - }, + gasLimit: gasRequired, storageDepositLimit: undefined, code: contract.wasm, data: U.hex.decode(constructor.selector), @@ -60,11 +59,11 @@ function instantiateContractTx() { } ) return C.events(tx, finalizedIn).next((events) => { - const extrinsicFailed = events.some((e) => + const extrinsicFailedEvent = events.find((e) => e.event?.type === "System" && e.event?.value?.type === "ExtrinsicFailed" ) - if (extrinsicFailed) { - return new Error("extrinsic failed") + if (extrinsicFailedEvent) { + return new ExtrinsicFailed(extrinsicFailedEvent) } const event = events.find((e) => e.event?.type === "Contracts" && e.event?.value?.type === "Instantiated" @@ -73,6 +72,18 @@ function instantiateContractTx() { }) } +class ExtrinsicFailed extends Error { + override readonly name = "ExtrinsicFailedError" + constructor( + override readonly cause: { + event?: Record + phase: { value: number } + }, + ) { + super() + } +} + function preSubmitContractInstantiateDryRunGasEstimate( message: C.M.ContractMetadata.Constructor, code: Uint8Array, @@ -162,7 +173,7 @@ class SmartContract { sign: C.Z.$, ) { const message = this.#getMessageByLabel(messageLabel)! - const [$args, _] = this.#getMessageCodecs(message) + const [$args, _, $events] = this.#getMessageCodecs(message) const data = $args.encode([U.hex.decode(message.selector), ...args]) const value = this.#preSubmitContractCallDryRunGasEstimate(origin, data) .next(({ gasRequired }) => { @@ -171,10 +182,7 @@ class SmartContract { dest: C.MultiAddress.Id(this.contractAddress), value: 0n, data, - gasLimit: { - refTime: gasRequired.refTime, - proofSize: gasRequired.proofSize, - }, + gasLimit: gasRequired, storageDepositLimit: undefined, } }) @@ -197,6 +205,14 @@ class SmartContract { } ) return C.Z.ls(finalizedIn, C.events(tx, finalizedIn)) + .next(([finalizedIn, events]) => { + const contractEvents: any[] = events + .filter( + (e) => e.event?.type === "Contracts" && e.event?.value?.type === "ContractEmitted", + ) + .map((e) => $events.decode(e.event?.value.data)) + return [finalizedIn, events, contractEvents] + }) } // TODO: codegen each contract message as a method @@ -207,18 +223,33 @@ class SmartContract { #getMessageCodecs( message: C.M.ContractMetadata.Message, - ): [C.$.Codec, C.$.Codec] { + ): [C.$.Codec, C.$.Codec, C.$.Codec] { + // TODO: cache on initialization const argCodecs = [ // message selector C.$.sizedUint8Array(U.hex.decode(message.selector).length), // message args ...message.args.map((arg) => this.deriveCodec(arg.type.type)), ] + // TODO: cache on initialization const $result = message.returnType !== null ? this.deriveCodec(message.returnType.type) : C.$.constant(null) + // FIXME: this is not message specific + const $events = C.$.taggedUnion( + "type", + this.metadata.V3.spec.events + .map((e) => [ + e.label, + [ + "value", + C.$.tuple(...e.args + .map((a) => this.deriveCodec(a.type.type))), + ], + ]), + ) // @ts-ignore ... - return [C.$.tuple(...argCodecs), $result] + return [C.$.tuple(...argCodecs), $result, $events] } #preSubmitContractCallDryRunGasEstimate( @@ -243,6 +274,10 @@ class SmartContract { } } +const prefix = U.throwIfError(await ss58Prefix.run()) +const contractAddress = U.throwIfError(await instantiateContractTx().run()) +console.log("Deployed Contract address", U.ss58.encode(prefix, contractAddress)) + const flipperContract = new SmartContract(contract.metadata, contractAddress) console.log(".get", await flipperContract.call(T.alice.publicKey, "get", []).run()) console.log( @@ -266,12 +301,18 @@ console.log( ) console.log(".get_count", await flipperContract.call(T.alice.publicKey, "get_count", []).run()) console.log( - ".m1(2,true) (multiple args/results)", - await flipperContract.call(T.alice.publicKey, "m1", [2, true]).run(), + ".inc_by_with_event(3) contract events", + U.throwIfError( + await flipperContract.tx(T.alice.publicKey, "inc_by_with_event", [3], T.alice.sign).run(), + )[2], +) +console.log( + ".method_returning_tuple(2,true)", + await flipperContract.call(T.alice.publicKey, "method_returning_tuple", [2, true]).run(), ) console.log( - ".m2(3,false) (multiple args/results)", - await flipperContract.call(T.alice.publicKey, "m1", [3, false]).run(), + ".method_returning_struct(3,false)", + await flipperContract.call(T.alice.publicKey, "method_returning_struct", [3, false]).run(), ) await zombienet.close() diff --git a/examples/smart_contract/flipper.contract b/examples/smart_contract/flipper.contract index cd1c91b6b..6c62caecb 100644 --- a/examples/smart_contract/flipper.contract +++ b/examples/smart_contract/flipper.contract @@ -1 +1 @@ -{"source":{"hash":"0xa64fbd08bc40eb972efb18c71ac812bd8219e9fd16b975f9ec070ce96ab32156","language":"ink! 3.4.0","compiler":"rustc 1.68.0-nightly","wasm":"0x0061736d01000000014e0d60037f7f7f017f60027f7f017f60037f7f7f0060027f7f0060057f7f7f7f7f0060047f7f7f7f0060017f0060000060047f7f7f7f017f60017f017e60067f7f7f7f7f7f0060017f017f6000017f02a30107057365616c30127365616c5f64656275675f6d6573736167650001057365616c30107365616c5f7365745f73746f726167650002057365616c30107365616c5f6765745f73746f726167650000057365616c300a7365616c5f696e7075740003057365616c300b7365616c5f72657475726e0002057365616c30167365616c5f76616c75655f7472616e73666572726564000303656e76066d656d6f7279020102100344430002020203000b0302060103030303020c030706070104030201000002010100060703060109040501010104080508040201010204000004050805010101010a01050a040501700110100501000608017f01418080040b071102066465706c6f7900180463616c6c001a0915010041010b0f103738442e2a41422946212324432b0acf5f432b01017f037f2002200346047f200005200020036a200120036a2d00003a0000200341016a21030c010b0b0b950202047f037e230041d0006b22032400200341306a2204200241186a290000370300200341286a2205200241106a290000370300200341206a2206200241086a2900003703002003420137033820032002290000370318200341aea204360240200342808001370244200341106a200341406b220220011008200341186a220120032802102003280214100120032003290318220720032903387c22083703182006200629030022092007200856ad7c22073703002005200529030022082007200954ad7c2207370300200420042903002007200854ad7c37030020034201370338200341aea204360240200342808001370244200341086a20022000100920012003280208200328020c1001200341d0006a24000b5602017f017e230041206b220324002001290200210420034100360218200320043703102002200341106a100d20012003290310370200200341086a20012003280218101520002003290308370300200341206a24000b6202017f017e230041206b220324002001290200210420034100360218200320043703102003200236021c200341106a2003411c6a4104100e20012003290310370200200341086a20012003280218101520002003290308370300200341206a24000b5401027f230041106b220224002002410036020c200020012002410c6a4104100b047f410205200228020c210341022001100c41ff0171220141017120014102461b0b3a000420002003360200200241106a24000b6001047f230041106b22032400200028020422042002492205450440200341086a41002002200028020022061047200120022003280208200328020c41b4a104103a20032002200420061047200020032903003702000b200341106a240020050b4001017f230041106b22012400200141003a000f20002001410f6a4101100b047f4102054101410220012d000f22004101461b410020001b0b200141106a24000b2601017f230041106b22022400200220003a000f20012002410f6a4101100e200241106a24000b6701037f230041106b220324002000280208220420026a2205200449044041909a04411c41cc9b04101e000b200341086a200420052000280200200028020441dc9b0410452003280208200328020c2001200241ec9b04103a20002005360208200341106a24000b5201017f230041206b220124002001410c6a4101360200200141146a4101360200200141a89e04360208200141003602002001410136021c200120003602182001200141186a360210200141b083041011000b910101017f230041306b22022400200241146a41013602002002411c6a4101360200200241a89e043602102002410036020820024102360224200220002d0000410274220041fca1046a28020036022c200220004190a2046a280200360228200141046a28020021002002200241206a3602182002200241286a36022020012802002000200241086a103b200241306a24000b840301037f230041206b22032400200341013a001820032001360214200320003602102003418c8a0436020c200341a89e04360208230041406a220224002002200341086a36020c2002410436022420022002410c6a360220410021004104210402400240024002400240024003402000200441d09a046a2802006a22012000490d0120012100200441086a22044114470d000b4100210041012104024020014110490d002001200120016a22034b200345720d0020034100480d022002200310282003210020022802002204450d060b2002410036021820022004360214200220003602102002410136023c20024102360234200241d09a04360230200241003602282002200241206a360238200241106a200241286a101f0d0241aca2042d000045044041ada2042d00004101710d060b2002280214200228021810004109470d030c040b41f08404411c41e89904101e000b1027000b41f086044133200241286a41b4850441908804101c000b41aca20441013a00000b41ada20441013a00000b000b4801027f230041106b220224002002410036020c024020012002410c6a4104100b450440200228020c21010c010b410121030b2000200136020420002003360200200241106a24000b4701017f230041106b220224002002410036020c024020012002410c6a4104100b4504402000200228020c360001200041003a00000c010b200041013a00000b200241106a24000b0b004100200020011004000b4501017f2002200128020422034b044041ac9a04412341fc9b04101e000b2001200320026b36020420012001280200220120026a36020020002002360204200020013602000b6c02027f027e230041206b22002400200041086a220142003703002000420037030020004110360214200020003602102000411036021c20002000411c6a1005200041106a200028021c10172001290300210220002903002103200041206a2400410541042002200384501b0b3701017f230041106b22022400200241086a410020012000280200200028020441f49c04104520002002290308370200200241106a24000bd40301057f230041306b220024002000027f02400240101641ff0171410546044020004180800136022c200041aea204360228200041286a1019200020002903283703082000200041086a101320002d00000d022000280001220141187621022001411076210320014108762104027f200141ff01712201419b01470440200141ed0147200441ff017141cb004772200341ff0171419d0147720d0441022002411b460d011a0c040b200441ff017141ae0147200341ff0171419d014772200241de0047720d03200041086a100c41ff017122014102460d0320014101710b2101101641ff01712102024002402001410247044020024105460d010c040b20024105470d03200041206a4200370300200041186a4200370300200041106a42003703002000420037030841004100200041086a10070c010b200041206a4200370300200041186a4200370300200041106a42003703002000420037030841002001200041086a10070b200041306a24000f0b200041043a0008200041086a100f000b41040c010b41030b3a0000200041146a41013602002000411c6a4101360200200041888404360210200041003602082000410136022c2000200041286a36021820002000360228200041086a41b083041011000b3301017f230041106b220124002001200028020436020c20002802002001410c6a10032000200128020c1017200141106a24000b9c0d02067f037e230041f0006b22002400024002400240027f02402000027f027f0240101641ff01712201410546044020004180800136025c200041aea204360258200041d8006a101920002000290358370328200041d0006a200041286a1013024020002d00500d002000280051220341187621012003411076210220034108762104024002400240024002400240200341ff0171220341fa016b0e050106060605000b2003411d460d0220034125460d012003412f470440200341e300470440200341b501460d05200341bb0147200441ff017141204772200241ff01712001413a4772720d07410421020c090b200441ff0171413a47200241ff017141a5014772200141d10047720d06410021014100210241000c090b200441ff017141860147200241ff017141db004772200141d90147720d05410121020c070b200441ff0171412c47200241ff017141be014772200141f10047720d04200041086a200041286a100a4102210220002d000c22014102460d04200141017121052000280208220141807e710c070b200441ff017141f90147200241ff017141a60147722001410947720d03200041106a200041286a100a20002d001422014102460d0320014101712105410321022000280210220141807e710c060b200441ff0171413247200241ff017141e10047722001419f0147720d02410521020c040b200441ff017141d70147200241ff017141b4014772200141f00147720d01410621020c030b200441ff017141db0047200241ff017141d8014772200141ea0147720d00200041186a200041286a101220002802180d0041072102200028021c220141807e710c030b41030c030b200020013a0028200041286a100f000b4100210141000b2104200041306a4200370300200041386a4200370300200041406b42003703002000420037032820004201370348200041808001360254200041aea204360250024002400240200041286a200041d0006a101b0e0400060601060b20002000290350370358200041d8006a100c41ff017122034102460d06200029034821062000420137034820002006200029032822077c22063703282000200029033022082006200754ad7c22063703302000200029033822072006200854ad7c2206370338200020002903402006200754ad7c370340200041808001360254200041aea2043602500240200041286a200041d0006a101b0e0400060601060b200020002903503703582000200041d8006a10122000280200450d010c060b230041106b220124002001411736020c200141988104360208230041206b220024002000410c6a4101360200200041146a4101360200200041a89e04360208200041003602002000410236021c2000200141086a3602182000200041186a360210200041b081041011000b200141ff01712004722104200028020421012000200341004722033a002420002001360220024002400240024002400240024002400240200241016b0e0706050504030200010b101641ff01714105470d07200041206a2004101d0c090b101641ff01714105460d050c060b101641ff01714105470d05200041206a417f101d0c070b101641ff01714105470d04200041206a4101101d0c060b101641ff01714105470d03230041206b22002400200041aea204360210200042808001370214200041086a200041106a200110090c090b101641ff01714105470d02230041206b22012400200141aea204360210200142808001370214230041206b22002400200141106a2202290200210620004100360218200020063703102000200436021c200041106a22042000411c6a4104100e20052004100d20022000290310370200200041086a200220002802181015200141086a2000290308370300200041206a24002001280208200128020c1014000b101641ff01714105470d01230041206b22002400200041aea204360210200042808001370214200041086a200041106a200310080c070b2003450c030b41040b3a0050200041346a41013602002000413c6a4101360200200041b48404360230200041003602282000410136025c2000200041d8006a3602382000200041d0006a360258200041286a41b083041011000b2000280220210120002d00240b21022001200241ff017141004741c083041007200041f0006a24000f0b200041e4006a4101360200200041ec006a4100360200200041f08204360260200041a89e0436026820004100360258200041d8006a41f882041011000b200041003a0058418080044127200041d8006a41dc810441888104101c000b2000280208200028020c1014000b5401017f230041106b220224002002200128020436020c200020012802002002410c6a100221002001200228020c1017410c21012000410b4d0440200041027441cca1046a28020021010b200241106a240020010b860101017f230041406a220524002005200136020c200520003602082005200336021420052002360210200541246a41023602002005412c6a41023602002005413c6a4103360200200541c08a0436022020054100360218200541023602342005200541306a3602282005200541106a3602382005200541086a360230200541186a20041011000b3201017f20014100482001200028020022016a220220014873450440200020023602000f0b41c08104411c41bc8404101e000b5001017f230041206b220324002003410c6a4101360200200341146a4100360200200341a89e04360210200341003602002003200136021c200320003602182003200341186a360208200320021011000b5501017f230041206b2202240020022000360204200241186a200141106a290200370300200241106a200141086a29020037030020022001290200370308200241046a41cc8404200241086a1020200241206a24000bee0301057f230041406a22032400200341033a003820034280808080800437033020034100360228200341003602202003200136021c20032000360218027f0240024020022802002201450440200241146a28020022004103742105200041ffffffff017121072002280210210441002101034020012005460d02200228020820016a220041046a28020022060440200328021820002802002006200328021c28020c1100000d040b200141086a2101200428020020042802042106200441086a2104200341186a2006110100450d000b0c020b200228020422074105742100200741ffffff3f71210703402000450d01200228020820046a220541046a28020022060440200328021820052802002006200328021c28020c1100000d030b20032001411c6a2d00003a00382003200141146a290200370330200341106a200228021022052001410c6a103920032003290310370320200341086a2005200141046a103920032003290308370328200441086a2104200041206b210020012802002106200141206a2101200520064103746a2205280200200341186a2005280204110100450d000b0c010b2002410c6a28020020074b04402003280218200228020820074103746a22002802002000280204200328021c28020c1100000d010b41000c010b41010b200341406b24000b0f00200028020020012002102241000b5801017f20022000280200200028020822036b4b044020002003200210251026200028020821030b200028020420036a2001200210061a2003200220036a22014b044041f08404411c41a08904101e000b200020013602080bbe0201027f230041106b220224000240024002400240200028020022002002410c6a027f0240024020014180014f04402002410036020c2001418010490d012001418080044f0d0220022001413f71418001723a000e20022001410c7641e001723a000c20022001410676413f71418001723a000d41030c030b200028020822032000280200460d030c040b20022001413f71418001723a000d2002200141067641c001723a000c41020c010b20022001413f71418001723a000f20022001410676413f71418001723a000e20022001410c76413f71418001723a000d2002200141127641077141f001723a000c41040b10220c020b20002003410110251026200028020821030b200028020420036a20013a0000200341016a2201450d01200020013602080b200241106a240041000f0b41f08404411c41908904101e000b4a01017f230041206b220224002000280200200241186a200141106a290200370300200241106a200141086a29020037030020022001290200370308200241086a101f200241206a24000b990401067f230041206b220324000240027f41002001200120026a22014b0d001a2000280200220220026a22052002490d012005200120012005491b22014108200141084b1b2201417f73411f7621040240200204402003410136021820032002360214200320002802043602100c010b200341003602180b200341106a2106230041106b220524002003027f0240027f0240200404400240200141004e044020062802080d012005200110282005280204210220052802000c040b0c040b20062802042208450440200541086a20011028200528020c210220052802080c030b20012102410041a4a204280200220420016a22072004490d021a2006280200210641a8a2042802002007490440200141ffff036a220741107640002202417f46200241ffff0371200247720d022002411074220420074180807c716a22022004490d0241a8a2042002360200200121024100200120046a22072004490d031a0b41a4a204200736020041002004450d021a20042006200810060c020b200320013602040c020b2001210241000b2204044020032004360204200341086a200236020041000c020b20032001360204200341086a410136020041010c010b200341086a410036020041010b360200200541106a240020032802004504402003280204210220002001360200200020023602044181808080780c010b200341086a2802000b200341206a24000f0b41908504412141b48604101e000b1b00024020004181808080784704402000450d01000b0f0b1027000b4601017f230041206b22002400200041146a41013602002000411c6a4100360200200041d88604360210200041a89e0436021820004100360208200041086a41e086041011000ba10101027f027f410041a4a204280200220320016a22022003490d001a024041a8a2042802002002490440200141ffff036a22022001490d012002411076220240002203417f46200341ffff0371200347720d012003411074220320024110746a22022003490d0141a8a20420023602004100200120036a22022003490d021a0b41a4a204200236020020030c010b41000b210220002001360204200020023602000b0300010b0e0020002802001a03400c000b000b0d004294d3af9489a8cbd9ed000bb20101017f230041106b2205240020022003490440230041306b220024002000200236020420002003360200200041146a41023602002000411c6a41023602002000412c6a410536020020004198900436021020004100360208200041053602242000200041206a3602182000200041046a36022820002000360220200041086a20041011000b200541086a200320022001102d200528020c21012000200528020836020020002001360204200541106a24000b14002000200120022003419ca00441d0890410480bd806020b7f027e230041406a2203240020002802002202ad210d0240024002400240024002400240024020024190ce004f044041272100200d210e0240034020004104490d01200341196a20006a220241046b200e200e4290ce0080220d4290ce007e7da7220441ffff037141e4006e220641017441c78b046a2f00003b0000200241026b2004200641e4006c6b41ffff037141017441c78b046a2f00003b0000200041046b2100200e42ffc1d72f56200d210e0d000b200da7220241e3004d0d0320004102490d090c020b0c080b41272100200241e3004b0d002002410a490d040c020b200041026b2200200341196a6a200da72202200241ffff037141e4006e220241e4006c6b41ffff037141017441c78b046a2f00003b00000b2002410a490d01200041024f0d000c050b200041026b2200200341196a6a200241017441c78b046a2f00003b00000c020b2000450d030b200041016b2200200341196a6a200241306a3a00000b200041274b0d01412820006b412720006b22062001280218220541017122071b2102410021042005410471044041a89e042104200241a89e0441a89e04102f20026a22024b0d010b412b418080c40020071b2107200341196a20006a2108024020012802084504404101210020012802002202200141046a28020022012007200410320d01200220082006200128020c11000021000c010b024020022001410c6a28020022094904402005410871450d01200128021c210b2001413036021c20012d0020210c41012100200141013a002020012802002205200141046a280200220a2007200410320d02200341106a2001200920026b4101103320032802142202418080c400460d022003280210200520082006200a28020c1100000d0220022005200a10340d022001200c3a00202001200b36021c410021000c020b4101210020012802002202200141046a28020022012007200410320d01200220082006200128020c11000021000c010b41012100200341086a2001200920026b41011033200328020c2205418080c400460d00200328020820012802002202200141046a28020022012007200410320d00200220082006200128020c1100000d00200520022001103421000b200341406b240020000f0b41b08904411c41808e04101e000b41d08904412141f89904101e000ba704010a7f230041106b2203240002400240200020016b22024110490d002002200141036a417c7120016b220049200041044b720d00200220006b22044104490d002001200010302206200020016a22082004417c716a200441037110306a220220064f0440200441027621050240024003402005450d05200320082005200541c001200541c001491b41f091041031200328020c21052003280208210820032003280200200328020422002000417c7141f092041031200328020c210920032802082107024020032802042200450440410021010c010b2003280200220420004102746a210a4100210103402004220641106a2104410021000240034020012001200020066a280200220b417f73410776200b410676724181828408716a22014d0440200041046a22004110470d010c020b0b41b08904411c41e89404101e000b2004200a470d000b0b20022002200141087641ff81fc0771200141ff81fc07716a418180046c4110766a22024b0d012009450d000b200941027421004100210103402001200120072802002204417f734107762004410676724181828408716a22014b0d02200741046a2107200041046b22000d000b20022002200141087641ff81fc0771200141ff81fc07716a418180046c4110766a22024d0d0441b08904411c41989504101e000b41b08904411c41f89404101e000b41b08904411c41889504101e000b41b08904411c41d89404101e000b20012002103021020b200341106a240020020b4601017f200145044041000f0b024003402002200220002c000041bf7f4a6a22024b0d01200041016a2100200141016b22010d000b20020f0b41b08904411c41e89904101e000b3e00200220034f044020002003360204200020013602002000410c6a200220036b3602002000200120034102746a3602080f0b41ac9a0441232004101e000b39000240027f2002418080c40047044041012000200220012802101101000d011a0b20030d0141000b0f0b200020034100200128020c1100000bae0101027f20022104024002400240200320012d0020220320034103461b41ff0171220341016b0e03010001020b200241016a2203044020034101762104200241017621030c020b41b08904411c41908e04101e000b41002104200221030b200341016a2102200128021c2103200128020421052001280200210102400340200241016b2202450d01200120032005280210110100450d000b418080c40021030b20002003360204200020043602000b3201017f027f0340200020002004460d011a200441016a2104200220012003280210110100450d000b200441016b0b2000490b4b01017f230041106b22052400200120034d0440200541086a410020012002102d200528020c21012000200528020836020020002001360204200541106a24000f0b2001200320041036000b7501017f230041306b220324002003200136020420032000360200200341146a41023602002003411c6a41023602002003412c6a4105360200200341b8900436021020034100360208200341053602242003200341206a3602182003200341046a36022820032003360220200341086a20021011000bea04010b7f230041106b2209240020002802042104200028020021030240024002402001280208220b410147200128021022024101477145044020024101470d02200320046a210c200141146a28020041016a210a410021022003210003402000200c460d03027f024020002c0000220641004e0440200041016a2105200641ff017121070c010b20002d0001413f7121052006411f7121072006415f4d044020074106742005722107200041026a21050c010b20002d0002413f7120054106747221082006417049044020082007410c74722107200041036a21050c010b200041046a210520022106418080c4002007411274418080f0007120002d0003413f71200841067472722207418080c400460d011a0b2002200520006b6a22062002490d0320070b2108200a41016b220a044020052100200621022008418080c400470d010c040b0b2008418080c400460d02024002402002450d00200220044f04404100210020022004460d010c020b41002100200220036a2c00004140480d010b200321000b2002200420001b21042000200320001b21030c020b200128020020032004200128020428020c11000021000c020b41b08904411c41989604101e000b200b450440200128020020032004200128020428020c11000021000c010b2001410c6a2802002200200320046a2003102f22024b0440200941086a2001200020026b4100103341012100200928020c2202418080c400460d0120092802082001280200220520032004200141046a280200220128020c1100000d01200220052001103421000c010b200128020020032004200128020428020c11000021000b200941106a240020000b140020002802002001200028020428020c1101000b5501027f0240027f02400240200228020041016b0e020103000b200241046a0c010b200120022802044103746a22012802044106470d0120012802000b2802002104410121030b20002004360204200020033602000b8501002001200346044020002002200110061a0f0b230041306b220024002000200336020420002001360200200041146a41033602002000411c6a41023602002000412c6a4105360200200041d0930436021020004100360208200041053602242000200041206a360218200020003602282000200041046a360220200041086a20041011000b4901017f230041206b22032400200341186a200241106a290200370300200341106a200241086a2902003703002003200229020037030820002001200341086a1020200341206a24000bda08010b7f23004190016b22032400200341003b0184012003410a3602800120034281808080a00137037820032002360274200341003602702003200236026c200320013602682003200236026420034100360260200028020421062000280200210720002802082108200341fc006a2109027f0340024002400240024020032d008501450440200341d8006a2003280268220c200328026c20032802702003280274103d0240024020032802582201450d00200328025c2100034002400240024002400240027f0240024002400240200328027822020440200220096a41016b2d00002104200041084f04402001200141036a417c712202460440200041086b210a410021020c040b200341d0006a200220016b22022000200020024b1b22022001200041948f041035200341c8006a200420032802502003280254103e20032802484101470d02200328024c21010c050b200341306a200420012000103e2003280234210120032802300c050b41d08904412141b09804101e000b2002200041086b220a4b0d010b200441818284086c210b0340200241046a22052002490d04200120026a280200200b73220d417f73200d41818284086b71200120056a280200200b732205417f73200541818284086b7172418081828478710d012002200241086a22024b0d072002200a4d0d000b0b200341406b20012000200241c48f04102c200341386a200420032802402003280244103e410020032802384101470d011a2002200328023c6a220120024f0d0041b08904411c41d48f04101e000b41010b4101460440200141016a2200450d022000200328027022006a22022000490d0320032002360270200220032802782200490d05200341286a2003280268200328026c200220006b2002103d20032802282202450d05200328022c2100200341206a20032802782009410441e0980410352002200020032802202003280224103f450d05200341186a200328026020032802702200200c104020032000360260200328021c2102200328021821000c080b200320032802743602700c060b41b08904411c41a48f04101e000b41b08904411c41c09804101e000b41b08904411c41d09804101e000b41b08904411c41b48f04101e000b200341106a2003280268200328026c20032802702003280274103d20032802142100200328021022010d000b0b4100210020032d0085010d00024020032d008401044020032802642101200328026021040c010b2003280264220120032802602204490d0420012004460d010b200341013a008501200341086a2004200120032802681040200328020c2102200328020821000b20000d010b41000c050b20082d0000450d01200741d08a044104200628020c110000450d010c020b41d08904412141a89604101e000b2003410a36028c0120082002047f200320002002200241016b41809304102c2003418c016a410120032802002003280204103f0541000b3a0000200720002002200628020c110000450d010b0b41010b20034190016a24000b4c01037f230041106b220524002002200449200320044b72450440200541086a200320042001102d200528020c2107200528020821060b2000200736020420002006360200200541106a24000b5701027f024002402003450440410021030c010b200141ff017121054101210103402005200220046a2d0000460440200421030c030b2003200441016a2204470d000b0b410021010b20002003360204200020013602000b4d01017f2001200346047f027f034041002001450d011a200141016b210120022d0000210320002d00002104200041016a2100200241016a210220032004460d000b200420036b0b0541010b450b1400200020012002200341ac970441d0890410480b5801027f230041206b22022400200128020421032001280200200241186a2000280200220041106a290200370300200241106a200041086a290200370300200220002902003703082003200241086a1020200241206a24000b0b002000280200200110370b1800200128020041c4a1044105200128020428020c1100000b990301037f230041406a220224002000280200210341012100024020012802002204419c8a04410c200141046a280200220128020c1100000d0002402003280208220004402002200036020c200241346a4102360200410121002002413c6a4101360200200241ac8a0436023020024100360228200241073602142002200241106a36023820022002410c6a36021020042001200241286a103b450d010c020b20032802002200200328020428020c11090042c8b5e0cfca86dbd3897f520d002002200036020c200241346a4102360200410121002002413c6a4101360200200241ac8a0436023020024100360228200241083602142002200241106a36023820022002410c6a36021020042001200241286a103b0d010b200328020c21002002411c6a4103360200200241246a41033602002002413c6a4105360200200241346a4105360200200241f489043602182002410036021020022000410c6a3602382002200041086a3602302002410236022c200220003602282002200241286a36022020042001200241106a103b21000b200241406b240020000ba201000240200120024d0440200220044d0d012002200420051036000b230041306b220024002000200236020420002001360200200041146a41023602002000411c6a41023602002000412c6a4105360200200041ec900436021020004100360208200041053602242000200041206a3602182000200041046a36022820002000360220200041086a20051011000b2000200220016b3602042000200120036a3602000b980401047f230041106b22022400024002400240024002400240024002400240024002400240024020002d000041016b0e0b0102030405060708090a0b000b410121002001280200220341a29e0441062001280204220528020c22041100000d0b024020012d0018410471450440200341d88a04410120041100000d0d200341c4a10441052004110000450d010c0d0b200341d68a04410220041100000d0c2002200536020420022003360200200241013a000f20022002410f6a360208200241c4a1044105103c0d0c200241d48a044102103c0d0c0b200341f189044101200411000021000c0b0b200128020041959e04410d200128020428020c11000021000c0a0b200128020041879e04410e200128020428020c11000021000c090b200128020041fc9d04410b200128020428020c11000021000c080b200128020041e29d04411a200128020428020c11000021000c070b200128020041d49d04410e200128020428020c11000021000c060b200128020041c49d044110200128020428020c11000021000c050b200128020041b89d04410c200128020428020c11000021000c040b200128020041ad9d04410b200128020428020c11000021000c030b200128020041a69d044107200128020428020c11000021000c020b200128020041979d04410f200128020428020c11000021000c010b200128020041849d044113200128020428020c11000021000b200241106a240020000b14002000200120022003419ca00441b0a00410480b2800200120024d04402000200220016b3602042000200120036a3602000f0b200541212004101e000b0b87220400418080040bbd03636f756c64206e6f742070726f7065726c79206465636f64652073746f7261676520656e7472792f55736572732f7061726974792f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f696e6b5f73746f726167652d332e342e302f7372632f7472616974732f6d6f642e72732700010061000000a20000000a00000073746f7261676520656e7472792077617320656d707479002700010061000000a30000000a000000617474656d707420746f206164642077697468206f766572666c6f770900000001000000010000000a0000002f55736572732f7061726974792f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f696e6b5f656e762d332e342e302f7372632f656e67696e652f6f6e5f636861696e2f696d706c732e7273656e636f756e746572656420756e6578706563746564206572726f72540101001c000000ec00010068000000f6000000170000002f55736572732f7061726974792f436f64652f3466756e2f666c69707065722f6c69622e72730000880101002600000008000000050041e083040b81016469737061746368696e6720696e6b2120636f6e7374727563746f72206661696c65643a20000000e0010100250000006469737061746368696e6720696e6b21206d657373616765206661696c65643a20000000100201002100000088010100260000005b0000000d0000000900000004000000040000000b0000000c0000000d0041f084040b9515617474656d707420746f206164642077697468206f766572666c6f7700000000617474656d707420746f206d756c7469706c792077697468206f766572666c6f770000000900000000000000010000000e0000002f55736572732f7061726974792f2e7275737475702f746f6f6c636861696e732f6e696768746c792d616172636836342d6170706c652d64617277696e2f6c69622f727573746c69622f7372632f727573742f6c6962726172792f616c6c6f632f7372632f7261775f7665632e727300c40201006f0000008a0100001c0000006361706163697479206f766572666c6f770000004403010011000000c40201006f00000006020000050000006120666f726d617474696e6720747261697420696d706c656d656e746174696f6e2072657475726e656420616e206572726f722f55736572732f7061726974792f2e7275737475702f746f6f6c636861696e732f6e696768746c792d616172636836342d6170706c652d64617277696e2f6c69622f727573746c69622f7372632f727573742f6c6962726172792f616c6c6f632f7372632f666d742e72730000a30301006b00000064020000200000002f55736572732f7061726974792f2e7275737475702f746f6f6c636861696e732f6e696768746c792d616172636836342d6170706c652d64617277696e2f6c69622f727573746c69622f7372632f727573742f6c6962726172792f616c6c6f632f7372632f7665632f6d6f642e727300200401006f000000300700000d000000200401006f0000009e07000009000000617474656d707420746f206164642077697468206f766572666c6f7700000000617474656d707420746f2073756274726163742077697468206f766572666c6f77293a00280f010000000000f204010001000000f2040100010000000900000000000000010000000f00000070616e69636b65642061742027272c20280501000100000029050100030000003a200000280f0100000000003c05010002000000202020202c0a280a282f55736572732f7061726974792f2e7275737475702f746f6f6c636861696e732f6e696768746c792d616172636836342d6170706c652d64617277696e2f6c69622f727573746c69622f7372632f727573742f6c6962726172792f636f72652f7372632f666d742f6e756d2e727330303031303230333034303530363037303830393130313131323133313431353136313731383139323032313232323332343235323632373238323933303331333233333334333533363337333833393430343134323433343434353436343734383439353035313532353335343535353635373538353936303631363236333634363536363637363836393730373137323733373437353736373737383739383038313832383338343835383638373838383939303931393239333934393539363937393839392f55736572732f7061726974792f2e7275737475702f746f6f6c636861696e732f6e696768746c792d616172636836342d6170706c652d64617277696e2f6c69622f727573746c69622f7372632f727573742f6c6962726172792f636f72652f7372632f666d742f6d6f642e72730000008f0601006e0000005d0500000d0000008f0601006e000000ed050000380000002f55736572732f7061726974792f2e7275737475702f746f6f6c636861696e732f6e696768746c792d616172636836342d6170706c652d64617277696e2f6c69622f727573746c69622f7372632f727573742f6c6962726172792f636f72652f7372632f736c6963652f6d656d6368722e72730020070100730000004e0000002f00000020070100730000005a0000001f00000020070100730000006300000009000000200701007300000068000000270000002007010073000000680000003e00000072616e676520737461727420696e64657820206f7574206f662072616e676520666f7220736c696365206f66206c656e67746820e407010012000000f60701002200000072616e676520656e6420696e646578202808010010000000f607010022000000736c69636520696e64657820737461727473206174202062757420656e6473206174200048080100160000005e0801000d0000002f55736572732f7061726974792f2e7275737475702f746f6f6c636861696e732f6e696768746c792d616172636836342d6170706c652d64617277696e2f6c69622f727573746c69622f7372632f727573742f6c6962726172792f636f72652f7372632f736c6963652f697465722e72730000007c08010071000000c4050000250000002f55736572732f7061726974792f2e7275737475702f746f6f6c636861696e732f6e696768746c792d616172636836342d6170706c652d64617277696e2f6c69622f727573746c69622f7372632f727573742f6c6962726172792f636f72652f7372632f736c6963652f6d6f642e72730009010070000000f30300002f0000000009010070000000d30800001e000000736f7572636520736c696365206c656e67746820282920646f6573206e6f74206d617463682064657374696e6174696f6e20736c696365206c656e67746820289009010015000000a50901002b000000f1040100010000002f55736572732f7061726974792f2e7275737475702f746f6f6c636861696e732f6e696768746c792d616172636836342d6170706c652d64617277696e2f6c69622f727573746c69622f7372632f727573742f6c6962726172792f636f72652f7372632f7374722f636f756e742e7273e8090100700000004700000015000000e8090100700000005400000011000000e8090100700000005a00000009000000e8090100700000006400000011000000e809010070000000660000000d0000002f55736572732f7061726974792f2e7275737475702f746f6f6c636861696e732f6e696768746c792d616172636836342d6170706c652d64617277696e2f6c69622f727573746c69622f7372632f727573742f6c6962726172792f636f72652f7372632f7374722f697465722e727300a80a01006f0000009100000011000000a80a01006f0000004c0200003c0000002f55736572732f7061726974792f2e7275737475702f746f6f6c636861696e732f6e696768746c792d616172636836342d6170706c652d64617277696e2f6c69622f727573746c69622f7372632f727573742f6c6962726172792f636f72652f7372632f7374722f7472616974732e7273000000380b010071000000ca000000130000002f55736572732f7061726974792f2e7275737475702f746f6f6c636861696e732f6e696768746c792d616172636836342d6170706c652d64617277696e2f6c69622f727573746c69622f7372632f727573742f6c6962726172792f636f72652f7372632f7374722f7061747465726e2e72730000bc0b010072000000a101000047000000bc0b010072000000b401000020000000bc0b010072000000b401000011000000bc0b010072000000b8010000260000002f55736572732f7061726974792f2e7275737475702f746f6f6c636861696e732f6e696768746c792d616172636836342d6170706c652d64617277696e2f6c69622f727573746c69622f7372632f727573742f6c6962726172792f636f72652f7372632f697465722f7472616974732f616363756d2e7273700c0100780000009500000001000000590501006e000000cd010000050041909a040b9308617474656d707420746f206164642077697468206f766572666c6f77617373657274696f6e206661696c65643a206d6964203c3d2073656c662e6c656e28290a280f0100000000004f0d0100010000002f55736572732f7061726974792f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f696e6b5f656e762d332e342e302f7372632f656e67696e652f6f6e5f636861696e2f6275666665722e7273000000600d010069000000580000001c000000600d0100690000005800000009000000600d0100690000005800000031000000600d0100690000008b000000210000002f55736572732f7061726974792f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f696e6b5f656e762d332e342e302f7372632f656e67696e652f6f6e5f636861696e2f6578742e727300000c0e0100660000008c0100001400000045636473615265636f766572794661696c65644c6f6767696e6744697361626c6564556e6b6e6f776e4e6f7443616c6c61626c65436f64654e6f74466f756e645f456e646f776d656e74546f6f4c6f775472616e736665724661696c65645f42656c6f7753756273697374656e63655468726573686f6c644b65794e6f74466f756e6443616c6c6565526576657274656443616c6c6565547261707065644465636f6465280f0100000000007061696420616e20756e70617961626c65206d657373616765636f756c64206e6f74207265616420696e707574756e61626c6520746f206465636f646520696e707574656e636f756e746572656420756e6b6e6f776e2073656c6563746f72756e61626c6520746f206465636f64652073656c6563746f722f55736572732f7061726974792f2e7275737475702f746f6f6c636861696e732f6e696768746c792d616172636836342d6170706c652d64617277696e2f6c69622f727573746c69622f7372632f727573742f6c6962726172792f636f72652f7372632f736c6963652f696e6465782e72730000a80f010072000000820100004700000000000000617474656d707420746f2073756274726163742077697468206f766572666c6f772f55736572732f7061726974792f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f7061726974792d7363616c652d636f6465632d332e322e312f7372632f636f6465632e727351100100630000007a0000000e0000004572726f72000000000000000100000002000000030000000400000005000000060000000700000008000000090000000c0000000b000000190000001c0000001600000014000000190000008f0f0100730f01005d0f0100490f0100300f01"},"contract":{"name":"flipper","version":"0.1.0","authors":["[your_name] <[your_email]>"]},"V3":{"spec":{"constructors":[{"args":[{"label":"init_value","type":{"displayName":["bool"],"type":0}}],"docs":["Constructor that initializes the `bool` value to the given `init_value`."],"label":"new","payable":false,"selector":"0x9bae9d5e"},{"args":[],"docs":["Constructor that initializes the `bool` value to `false`.","","Constructors can delegate to other constructors."],"label":"default","payable":false,"selector":"0xed4b9d1b"}],"docs":[],"events":[],"messages":[{"args":[],"docs":[" A message that can be called on instantiated contracts."," This one flips the value of the stored `bool` from `true`"," to `false` and vice versa."],"label":"flip","mutates":true,"payable":false,"returnType":null,"selector":"0x633aa551"},{"args":[],"docs":[" Simply returns the current value of our `bool`."],"label":"get","mutates":false,"payable":false,"returnType":{"displayName":["bool"],"type":0},"selector":"0x2f865bd9"},{"args":[{"label":"a","type":{"displayName":["u32"],"type":2}},{"label":"b","type":{"displayName":["bool"],"type":0}}],"docs":[" multiple arg method1."],"label":"m1","mutates":false,"payable":false,"returnType":{"displayName":[],"type":3},"selector":"0xfa2cbe71"},{"args":[{"label":"a","type":{"displayName":["u32"],"type":2}},{"label":"b","type":{"displayName":["bool"],"type":0}}],"docs":[" multiple arg method2."],"label":"m2","mutates":false,"payable":false,"returnType":{"displayName":["M2"],"type":4},"selector":"0x25f9a609"},{"args":[],"docs":[" get the current count."],"label":"get_count","mutates":false,"payable":false,"returnType":{"displayName":["i32"],"type":1},"selector":"0xbb20003a"},{"args":[],"docs":[" increment current count by 1"],"label":"inc","mutates":true,"payable":false,"returnType":null,"selector":"0x1d32619f"},{"args":[],"docs":[" decrement current count by 1"],"label":"dec","mutates":true,"payable":false,"returnType":null,"selector":"0xb5d7b4f0"},{"args":[{"label":"n","type":{"displayName":["i32"],"type":1}}],"docs":[" increment current count by n"],"label":"inc_by","mutates":true,"payable":false,"returnType":null,"selector":"0xfe5bd8ea"}]},"storage":{"struct":{"fields":[{"layout":{"cell":{"key":"0x0000000000000000000000000000000000000000000000000000000000000000","ty":0}},"name":"value"},{"layout":{"cell":{"key":"0x0100000000000000000000000000000000000000000000000000000000000000","ty":1}},"name":"count"}]}},"types":[{"id":0,"type":{"def":{"primitive":"bool"}}},{"id":1,"type":{"def":{"primitive":"i32"}}},{"id":2,"type":{"def":{"primitive":"u32"}}},{"id":3,"type":{"def":{"tuple":[2,0]}}},{"id":4,"type":{"def":{"composite":{"fields":[{"name":"a","type":2,"typeName":"u32"},{"name":"b","type":0,"typeName":"bool"}]}},"path":["flipper","flipper","M2"]}}]}} \ No newline at end of file +{"source":{"hash":"0x1e3986af05daee058d114887d78d251e7bad3700b7e5aa01741572162d7b3d85","language":"ink! 3.4.0","compiler":"rustc 1.68.0-nightly","wasm":"0x0061736d01000000014e0d60037f7f7f017f60027f7f017f60027f7f0060037f7f7f0060047f7f7f7f0060057f7f7f7f7f0060017f0060000060047f7f7f7f017f60017f017e60067f7f7f7f7f7f0060017f017f6000017f02ef010a057365616c30127365616c5f64656275675f6d6573736167650001057365616c30127365616c5f6465706f7369745f6576656e740004057365616c30107365616c5f7365745f73746f726167650003057365616c30107365616c5f6765745f73746f726167650000057365616c300a7365616c5f696e7075740002057365616c300b7365616c5f72657475726e0003057365616c30147365616c5f686173685f626c616b65325f3235360003057365616c300b7365616c5f63616c6c65720002057365616c30167365616c5f76616c75655f7472616e73666572726564000203656e76066d656d6f727902010210034d4c0004030303030302000b0203020206010202020202030c0207060701050202040503010000030101000607020601090504010101050804080503010103000005040804010101010a01040a04040501700110100501000608017f01418080040b071102066465706c6f7900210463616c6c00230915010041010b0f1843444f3a364c4d35512d2f304e370a916a4c2b01017f037f2002200346047f200005200020036a200120036a2d00003a0000200341016a21030c010b0b0b1400200020012002200341ac9b044180800410530b5001017f230041206b220324002003410c6a4101360200200341146a4100360200200341a8a004360210200341003602002003200136021c200320003602182003200341186a360208200320021019000b3901017f230041106b22032400200341086a410020012002100a200328020c21012000200328020836020020002001360204200341106a24000b950202047f037e230041d0006b22032400200341306a2204200241186a290000370300200341286a2205200241106a290000370300200341206a2206200241086a2900003703002003420137033820032002290000370318200341aea404360240200342808001370244200341106a200341406b22022001100e200341186a220120032802102003280214100220032003290318220720032903387c22083703182006200629030022092007200856ad7c22073703002005200529030022082007200954ad7c2207370300200420042903002007200854ad7c37030020034201370338200341aea404360240200342808001370244200341086a20022000100f20012003280208200328020c1002200341d0006a24000b5602017f017e230041206b220324002001290200210420034100360218200320043703102002200341106a101520012003290310370200200341086a20012003280218101e20002003290308370300200341206a24000b5602017f017e230041206b220324002001290200210420034100360218200320043703102002200341106a101320012003290310370200200341086a20012003280218101e20002003290308370300200341206a24000b5401027f230041106b220224002002410036020c200020012002410c6a41041011047f410205200228020c210341022001101241ff0171220141017120014102461b0b3a000420002003360200200241106a24000b6001047f230041106b22032400200028020422042002492205450440200341086a41002002200028020022061052200120022003280208200328020c41b4a304102920032002200420061052200020032903003702000b200341106a240020050b4001017f230041106b22012400200141003a000f20002001410f6a41011011047f4102054101410220012d000f22004101461b410020001b0b200141106a24000b2601017f230041106b220224002002200036020c20012002410c6a41041014200241106a24000b6701037f230041106b220324002000280208220420026a2205200449044041f09b04411c41ac9d04100b000b200341086a200420052000280200200028020441bc9d0410502003280208200328020c2001200241cc9d04102920002005360208200341106a24000b2601017f230041106b22022400200220003a000f20012002410f6a41011014200241106a24000b3d01017f230041106b22022400200241086a20014180800141aea404100a200228020c21012000200228020836020020002001360204200241106a24000b5201017f230041206b220124002001410c6a4101360200200141146a4101360200200141a8a004360208200141003602002001410136021c200120003602182001200141186a3602102001419c84041019000b910101017f230041306b22022400200241146a41013602002002411c6a4101360200200241a8a0043602102002410036020820024102360224200220002d0000410274220041fca3046a28020036022c200220004190a4046a280200360228200141046a28020021002002200241206a3602182002200241286a36022020012802002000200241086a1046200241306a24000b840301037f230041206b22032400200341013a00182003200136021420032000360210200341b08b0436020c200341a8a004360208230041406a220224002002200341086a36020c2002410436022420022002410c6a360220410021004104210402400240024002400240024003402000200441b09c046a2802006a22012000490d0120012100200441086a22044114470d000b4100210041012104024020014110490d002001200120016a22034b200345720d0020034100480d022002200310342003210020022802002204450d060b2002410036021820022004360214200220003602102002410136023c20024102360234200241b09c04360230200241003602282002200241206a360238200241106a200241286a102b0d0241aca4042d000045044041ada4042d00004101710d060b2002280214200228021810004109470d030c040b41d08504411c418c9b04100b000b1033000b41d087044133200241286a4194860441f088041025000b41aca40441013a00000b41ada40441013a00000b000b0a0020012000412010140b4801027f230041106b220224002002410036020c024020012002410c6a41041011450440200228020c21010c010b410121030b2000200136020420002003360200200241106a24000b4701017f230041106b220224002002410036020c024020012002410c6a410410114504402000200228020c360001200041003a00000c010b200041013a00000b200241106a24000b0b004100200020011005000b4501017f2002200128020422034b0440418c9c04412341fc9d04100b000b2001200320026b36020420012001280200220120026a36020020002002360204200020013602000b6c02027f027e230041206b22002400200041086a220142003703002000420037030020004110360214200020003602102000411036021c20002000411c6a1008200041106a200028021c10202001290300210220002903002103200041206a2400410541042002200384501b0b3701017f230041106b22022400200241086a410020012000280200200028020441f49e04105020002002290308370200200241106a24000bd40301057f230041306b220024002000027f02400240101f41ff0171410546044020004180800136022c200041aea404360228200041286a1022200020002903283703082000200041086a101c20002d00000d022000280001220141187621022001411076210320014108762104027f200141ff01712201419b01470440200141ed0147200441ff017141cb004772200341ff0171419d0147720d0441022002411b460d011a0c040b200441ff017141ae0147200341ff0171419d014772200241de0047720d03200041086a101241ff017122014102460d0320014101710b2101101f41ff01712102024002402001410247044020024105460d010c040b20024105470d03200041206a4200370300200041186a4200370300200041106a42003703002000420037030841004100200041086a100d0c010b200041206a4200370300200041186a4200370300200041106a42003703002000420037030841002001200041086a100d0b200041306a24000f0b200041043a0008200041086a1017000b41040c010b41030b3a0000200041146a41013602002000411c6a4101360200200041f48404360210200041003602082000410136022c2000200041286a36021820002000360228200041086a419c84041019000b3301017f230041106b220124002001200028020436020c20002802002001410c6a10042000200128020c1020200141106a24000b9e1502067f047e23004190026b220024000240024002402000027f027f0240101f41ff0171220141054604402000418080013602f401200041aea4043602f001200041f0016a1022200020002903f00137039801200041d0016a20004198016a101c024020002d00d0010d0020002800d10122044118762101200441107621022004410876210302400240200441ff01712204411d4704400240024002402004412f470440200441dc00460d02200441e300470440200441b501460d06200441bb01460d04200441d501460d07200441db01460d02200441fe0147200341ff017141db004772200241ff017141d80147200141ea014772720d08200041e0006a20004198016a101b20002802600d08410721022000280264220141807e710c0b0b200341ff0171413a47200241ff017141a5014772200141d10047720d07410021014100210241000c0a0b200341ff017141860147200241ff017141db004772200141d90147720d06410121020c080b200341ff017141c80047200241ff017141f90047722001410e47720d05200041d0006a20004198016a10104102210220002d005422014102460d05200141017121052000280250220141807e710c080b200341ff017141b30147200241ff017141e2014772200141d00147720d04200041d8006a20004198016a101020002d005c22014102460d0420014101712105410321022000280258220141807e710c070b200241ff0171200341ff0171412047722001413a47720d03410421020c050b200341ff0171413247200241ff017141e10047722001419f0147720d02410521020c040b200341ff017141d70147200241ff017141b4014772200141f00147720d01410621020c030b200341ff017141ce0047200241ff017141e70147722001411c47720d00200041e8006a20004198016a101b20002802680d0041082102200028026c220141807e710c030b41030c030b200020013a00980120004198016a1017000b4100210141000b2103200041a0016a4200370300200041a8016a4200370300200041b0016a42003703002000420037039801200042013703b8012000418080013602d401200041aea4043602d00102400240024020004198016a200041d0016a10240e0400040401040b200020002903d0013703f001200041f0016a101241ff017122044102460d0420002903b8012106200042013703b8012000200620002903980122077c220637039801200020002903a00122082006200754ad7c22063703a001200020002903a80122072006200854ad7c22063703a801200020002903b0012006200754ad7c3703b0012000418080013602d401200041aea4043602d001024020004198016a200041d0016a10240e0400040401040b200020002903d0013703f001200041c8006a200041f0016a101b2000280248450d010c040b230041106b220124002001411736020c200141bc8104360208230041206b220024002000410c6a4101360200200041146a4101360200200041a8a004360208200041003602002000410236021c2000200141086a3602182000200041186a360210200041d481041019000b200141ff01712003722103200028024c21012000200441004722043a0074200020013602700240027f024002400240024002400240024002400240024002400240200241016b0e080706060504030200010b101f41ff01714105470d0c200041f0006a20031026200041b0016a22014200370300200041a8016a22024200370300200041a0016a220342003703002000420037039801200041203602f401200020004198016a22043602f001200041203602d0012004200041d0016a1007200041f0016a220420002802d001102020004190016a2001290300220637030020004188016a2002290300220737030020004180016a200329030022083703002000200029039801220937037820002802702101200041a5016a2008370000200041ad016a2007370000200041b5016a2006370000200041013a009c0120002001360298012000200937009d01200041406b41001016200041003602f801200020002903403703f00120044104102720002802f8012202418180014f0d08200041386a20024180800141aea4041028200041003602c80120002903382106200041003602f801200020063703f001200041f0016a220341001027200341a8a00441001014200341e0830441141014200020002903f0013703c001200041306a200041c0016a20002802f801101e2000280230210420002802342103200041e8016a4200370300200041e0016a4200370300200041d8016a4200370300200042003703d0010240200341214f044020004188026a420037030020004180026a4200370300200041f8016a4200370300200042003703f00120042003200041f0016a22031006200041206a4120200041d0016a100c200028022020002802242003412041dc820410290c010b200041286a2003200041d0016a100c2000280228200028022c2004200341cc820410290b200041186a20021016200041003602f801200020002903183703f001200041d0016a200041f0016a101a2002200220002802f8016a22034b0d092000428080013702f401200041aea4043602f001200041106a200041f0016a22022003101e200041d8016a200041f8016a2802002203360200200020002903f00122063703d001200028021421042000280210200041c8016a2003360200200020063703c001200041003602f801200020063703f00120024100102720024101102720004198016a4105722002101a20002802980120021013200020002903f0013703c001200041086a200041c0016a20002802f801101e20042000280208200028020c100120002d00740c0b0b101f41ff01714105460d060c0b0b101f41ff01714105470d0a200041f0006a200310260c080b101f41ff01714105470d09200041f0006a417f10260c070b101f41ff01714105470d08200041f0006a410110260c060b101f41ff01714105470d07230041206b22002400200041aea404360210200042808001370214200041086a200041106a2001100f0c0b0b101f41ff01714105470d06230041206b22012400200141aea404360210200142808001370214230041206b22002400200141106a2202290200210620004100360218200020063703102003200041106a2203101320052003101520022000290310370200200041086a20022000280218101e200141086a2000290308370300200041206a24002001280208200128020c101d000b101f41ff01714105470d05230041206b22002400200041aea404360210200042808001370214200041086a200041106a2004100e0c090b2004450c030b20024180800141ec9d04102a000b41f08204411c41d08304100b000b2000280270210120002d00740b21022001200241ff017141004741ac8404100d20004190026a24000f0b41040b3a00d001200041a4016a4101360200200041ac016a4101360200200041a085043602a0012000410036029801200041013602f4012000200041f0016a3602a8012000200041d0016a3602f00120004198016a419c84041019000b200041fc016a410136020020004184026a4100360200200041b883043602f801200041a8a00436028002200041003602f001200041f0016a41c083041019000b200041003a00f00141a180044127200041f0016a418c830441ac81041025000b2000280208200028020c101d000b5401017f230041106b220224002002200128020436020c200020012802002002410c6a100321002001200228020c1020410c21012000410b4d0440200041027441cca3046a28020021010b200241106a240020010b860101017f230041406a220524002005200136020c200520003602082005200336021420052002360210200541246a41023602002005412c6a41023602002005413c6a4103360200200541e48b0436022020054100360218200541023602342005200541306a3602282005200541106a3602382005200541086a360230200541186a20041019000b3201017f20014100482001200028020022016a220220014873450440200020023602000f0b41f08204411c41a88504100b000ba10101027f20002802082202200028020422034904402000200241016a360208200028020020026a20013a00000f0b230041306b220024002000200336020420002002360200200041146a41023602002000411c6a41023602002000412c6a4105360200200041848b0436021020004100360208200041053602242000200041206a360218200020003602282000200041046a360220200041086a41dc9d041019000b1400200020012002200341ac9b0441c09b0410530b8501002001200346044020002002200110091a0f0b230041306b220024002000200336020420002001360200200041146a41033602002000411c6a41023602002000412c6a4105360200200041f4940436021020004100360208200041053602242000200041206a360218200020003602282000200041046a360220200041086a20041019000b0e0020002001200241bc910410540b5501017f230041206b2202240020022000360204200241186a200141106a290200370300200241106a200141086a29020037030020022001290200370308200241046a41b88504200241086a102c200241206a24000bee0301057f230041406a22032400200341033a003820034280808080800437033020034100360228200341003602202003200136021c20032000360218027f0240024020022802002201450440200241146a28020022004103742105200041ffffffff017121072002280210210441002101034020012005460d02200228020820016a220041046a28020022060440200328021820002802002006200328021c28020c1100000d040b200141086a2101200428020020042802042106200441086a2104200341186a2006110100450d000b0c020b200228020422074105742100200741ffffff3f71210703402000450d01200228020820046a220541046a28020022060440200328021820052802002006200328021c28020c1100000d030b20032001411c6a2d00003a00382003200141146a290200370330200341106a200228021022052001410c6a104520032003290310370320200341086a2005200141046a104520032003290308370328200441086a2104200041206b210020012802002106200141206a2101200520064103746a2205280200200341186a2005280204110100450d000b0c010b2002410c6a28020020074b04402003280218200228020820074103746a22002802002000280204200328021c28020c1100000d010b41000c010b41010b200341406b24000b0f00200028020020012002102e41000b5801017f20022000280200200028020822036b4b044020002003200210311032200028020821030b200028020420036a2001200210091a2003200220036a22014b044041d08504411c41808a04100b000b200020013602080bbe0201027f230041106b220224000240024002400240200028020022002002410c6a027f0240024020014180014f04402002410036020c2001418010490d012001418080044f0d0220022001413f71418001723a000e20022001410c7641e001723a000c20022001410676413f71418001723a000d41030c030b200028020822032000280200460d030c040b20022001413f71418001723a000d2002200141067641c001723a000c41020c010b20022001413f71418001723a000f20022001410676413f71418001723a000e20022001410c76413f71418001723a000d2002200141127641077141f001723a000c41040b102e0c020b20002003410110311032200028020821030b200028020420036a20013a0000200341016a2201450d01200020013602080b200241106a240041000f0b41d08504411c41f08904100b000b4a01017f230041206b220224002000280200200241186a200141106a290200370300200241106a200141086a29020037030020022001290200370308200241086a102b200241206a24000b990401067f230041206b220324000240027f41002001200120026a22014b0d001a2000280200220220026a22052002490d012005200120012005491b22014108200141084b1b2201417f73411f7621040240200204402003410136021820032002360214200320002802043602100c010b200341003602180b200341106a2106230041106b220524002003027f0240027f0240200404400240200141004e044020062802080d012005200110342005280204210220052802000c040b0c040b20062802042208450440200541086a20011034200528020c210220052802080c030b20012102410041a4a404280200220420016a22072004490d021a2006280200210641a8a4042802002007490440200141ffff036a220741107640002202417f46200241ffff0371200247720d022002411074220420074180807c716a22022004490d0241a8a4042002360200200121024100200120046a22072004490d031a0b41a4a404200736020041002004450d021a20042006200810090c020b200320013602040c020b2001210241000b2204044020032004360204200341086a200236020041000c020b20032001360204200341086a410136020041010c010b200341086a410036020041010b360200200541106a240020032802004504402003280204210220002001360200200020023602044181808080780c010b200341086a2802000b200341206a24000f0b41f08504412141948704100b000b1b00024020004181808080784704402000450d01000b0f0b1033000b4601017f230041206b22002400200041146a41013602002000411c6a4100360200200041b88704360210200041a8a00436021820004100360208200041086a41c087041019000ba10101027f027f410041a4a404280200220320016a22022003490d001a024041a8a4042802002002490440200141ffff036a22022001490d012002411076220240002203417f46200341ffff0371200347720d012003411074220320024110746a22022003490d0141a8a40420023602004100200120036a22022003490d021a0b41a4a404200236020020030c010b41000b210220002001360204200020023602000b0300010b0e0020002802001a03400c000b000b0c0042b7f8dbfe9ee1aecb430b4a01017f230041106b2205240020022003490440200320022004102a000b200541086a2003200220011039200528020c21012000200528020836020020002001360204200541106a24000b14002000200120022003419ca20441b08a0410530bd806020b7f027e230041406a2203240020002802002202ad210d0240024002400240024002400240024020024190ce004f044041272100200d210e0240034020004104490d01200341196a20006a220241046b200e200e4290ce0080220d4290ce007e7da7220441ffff037141e4006e220641017441eb8c046a2f00003b0000200241026b2004200641e4006c6b41ffff037141017441eb8c046a2f00003b0000200041046b2100200e42ffc1d72f56200d210e0d000b200da7220241e3004d0d0320004102490d090c020b0c080b41272100200241e3004b0d002002410a490d040c020b200041026b2200200341196a6a200da72202200241ffff037141e4006e220241e4006c6b41ffff037141017441eb8c046a2f00003b00000b2002410a490d01200041024f0d000c050b200041026b2200200341196a6a200241017441eb8c046a2f00003b00000c020b2000450d030b200041016b2200200341196a6a200241306a3a00000b200041274b0d01412820006b412720006b22062001280218220541017122071b2102410021042005410471044041a8a0042104200241a8a00441a8a004103b20026a22024b0d010b412b418080c40020071b2107200341196a20006a2108024020012802084504404101210020012802002202200141046a280200220120072004103e0d01200220082006200128020c11000021000c010b024020022001410c6a28020022094904402005410871450d01200128021c210b2001413036021c20012d0020210c41012100200141013a002020012802002205200141046a280200220a20072004103e0d02200341106a2001200920026b4101103f20032802142202418080c400460d022003280210200520082006200a28020c1100000d0220022005200a10400d022001200c3a00202001200b36021c410021000c020b4101210020012802002202200141046a280200220120072004103e0d01200220082006200128020c11000021000c010b41012100200341086a2001200920026b4101103f200328020c2205418080c400460d00200328020820012802002202200141046a280200220120072004103e0d00200220082006200128020c1100000d00200520022001104021000b200341406b240020000f0b41908a04411c41a48f04100b000b41b08a044121419c9b04100b000ba704010a7f230041106b2203240002400240200020016b22024110490d002002200141036a417c7120016b220049200041044b720d00200220006b22044104490d0020012000103c2206200020016a22082004417c716a2004410371103c6a220220064f0440200441027621050240024003402005450d05200320082005200541c001200541c001491b41949304103d200328020c21052003280208210820032003280200200328020422002000417c7141949404103d200328020c210920032802082107024020032802042200450440410021010c010b2003280200220420004102746a210a4100210103402004220641106a2104410021000240034020012001200020066a280200220b417f73410776200b410676724181828408716a22014d0440200041046a22004110470d010c020b0b41908a04411c418c9604100b000b2004200a470d000b0b20022002200141087641ff81fc0771200141ff81fc07716a418180046c4110766a22024b0d012009450d000b200941027421004100210103402001200120072802002204417f734107762004410676724181828408716a22014b0d02200741046a2107200041046b22000d000b20022002200141087641ff81fc0771200141ff81fc07716a418180046c4110766a22024d0d0441908a04411c41bc9604100b000b41908a04411c419c9604100b000b41908a04411c41ac9604100b000b41908a04411c41fc9504100b000b20012002103c21020b200341106a240020020b4601017f200145044041000f0b024003402002200220002c000041bf7f4a6a22024b0d01200041016a2100200141016b22010d000b20020f0b41908a04411c418c9b04100b000b3e00200220034f044020002003360204200020013602002000410c6a200220036b3602002000200120034102746a3602080f0b418c9c0441232004100b000b39000240027f2002418080c40047044041012000200220012802101101000d011a0b20030d0141000b0f0b200020034100200128020c1100000bae0101027f20022104024002400240200320012d0020220320034103461b41ff0171220341016b0e03010001020b200241016a2203044020034101762104200241017621030c020b41908a04411c41b48f04100b000b41002104200221030b200341016a2102200128021c2103200128020421052001280200210102400340200241016b2202450d01200120032005280210110100450d000b418080c40021030b20002003360204200020043602000b3201017f027f0340200020002004460d011a200441016a2104200220012003280210110100450d000b200441016b0b2000490b4b01017f230041106b22052400200120034d0440200541086a4100200120021039200528020c21012000200528020836020020002001360204200541106a24000f0b2001200320041042000b0e0020002001200241dc910410540bea04010b7f230041106b2209240020002802042104200028020021030240024002402001280208220b410147200128021022024101477145044020024101470d02200320046a210c200141146a28020041016a210a410021022003210003402000200c460d03027f024020002c0000220641004e0440200041016a2105200641ff017121070c010b20002d0001413f7121052006411f7121072006415f4d044020074106742005722107200041026a21050c010b20002d0002413f7120054106747221082006417049044020082007410c74722107200041036a21050c010b200041046a210520022106418080c4002007411274418080f0007120002d0003413f71200841067472722207418080c400460d011a0b2002200520006b6a22062002490d0320070b2108200a41016b220a044020052100200621022008418080c400470d010c040b0b2008418080c400460d02024002402002450d00200220044f04404100210020022004460d010c020b41002100200220036a2c00004140480d010b200321000b2002200420001b21042000200320001b21030c020b200128020020032004200128020428020c11000021000c020b41908a04411c41bc9704100b000b200b450440200128020020032004200128020428020c11000021000c010b2001410c6a2802002200200320046a2003103b22024b0440200941086a2001200020026b4100103f41012100200928020c2202418080c400460d0120092802082001280200220520032004200141046a280200220128020c1100000d01200220052001104021000c010b200128020020032004200128020428020c11000021000b200941106a240020000b140020002802002001200028020428020c1101000b5501027f0240027f02400240200228020041016b0e020103000b200241046a0c010b200120022802044103746a22012802044106470d0120012802000b2802002104410121030b20002004360204200020033602000b4901017f230041206b22032400200341186a200241106a290200370300200341106a200241086a2902003703002003200229020037030820002001200341086a102c200341206a24000bda08010b7f23004190016b22032400200341003b0184012003410a3602800120034281808080a00137037820032002360274200341003602702003200236026c200320013602682003200236026420034100360260200028020421062000280200210720002802082108200341fc006a2109027f0340024002400240024020032d008501450440200341d8006a2003280268220c200328026c2003280270200328027410480240024020032802582201450d00200328025c2100034002400240024002400240027f0240024002400240200328027822020440200220096a41016b2d00002104200041084f04402001200141036a417c712202460440200041086b210a410021020c040b200341d0006a200220016b22022000200020024b1b22022001200041b890041041200341c8006a200420032802502003280254104920032802484101470d02200328024c21010c050b200341306a20042001200010492003280234210120032802300c050b41b08a04412141d49904100b000b2002200041086b220a4b0d010b200441818284086c210b0340200241046a22052002490d04200120026a280200200b73220d417f73200d41818284086b71200120056a280200200b732205417f73200541818284086b7172418081828478710d012002200241086a22024b0d072002200a4d0d000b0b200341406b20012000200241e890041038200341386a2004200328024020032802441049410020032802384101470d011a2002200328023c6a220120024f0d0041908a04411c41f89004100b000b41010b4101460440200141016a2200450d022000200328027022006a22022000490d0320032002360270200220032802782200490d05200341286a2003280268200328026c200220006b2002104820032802282202450d05200328022c2100200341206a20032802782009410441849a0410412002200020032802202003280224104a450d05200341186a200328026020032802702200200c104b20032000360260200328021c2102200328021821000c080b200320032802743602700c060b41908a04411c41c89004100b000b41908a04411c41e49904100b000b41908a04411c41f49904100b000b41908a04411c41d89004100b000b200341106a2003280268200328026c20032802702003280274104820032802142100200328021022010d000b0b4100210020032d0085010d00024020032d008401044020032802642101200328026021040c010b2003280264220120032802602204490d0420012004460d010b200341013a008501200341086a200420012003280268104b200328020c2102200328020821000b20000d010b41000c050b20082d0000450d01200741f48b044104200628020c110000450d010c020b41b08a04412141cc9704100b000b2003410a36028c0120082002047f200320002002200241016b41a4940410382003418c016a410120032802002003280204104a0541000b3a0000200720002002200628020c110000450d010b0b41010b20034190016a24000b4c01037f230041106b220524002002200449200320044b72450440200541086a2003200420011039200528020c2107200528020821060b2000200736020420002006360200200541106a24000b5701027f024002402003450440410021030c010b200141ff017121054101210103402005200220046a2d0000460440200421030c030b2003200441016a2204470d000b0b410021010b20002003360204200020013602000b4d01017f2001200346047f027f034041002001450d011a200141016b210120022d0000210320002d00002104200041016a2100200241016a210220032004460d000b200420036b0b0541010b450b1400200020012002200341d0980441b08a0410530b5801027f230041206b22022400200128020421032001280200200241186a2000280200220041106a290200370300200241106a200041086a290200370300200220002902003703082003200241086a102c200241206a24000b0b002000280200200110430b1800200128020041c4a3044105200128020428020c1100000b990301037f230041406a22022400200028020021034101210002402001280200220441c08b04410c200141046a280200220128020c1100000d0002402003280208220004402002200036020c200241346a4102360200410121002002413c6a4101360200200241d08b0436023020024100360228200241073602142002200241106a36023820022002410c6a36021020042001200241286a1046450d010c020b20032802002200200328020428020c11090042c8b5e0cfca86dbd3897f520d002002200036020c200241346a4102360200410121002002413c6a4101360200200241d08b0436023020024100360228200241083602142002200241106a36023820022002410c6a36021020042001200241286a10460d010b200328020c21002002411c6a4103360200200241246a41033602002002413c6a4105360200200241346a4105360200200241988b043602182002410036021020022000410c6a3602382002200041086a3602302002410236022c200220003602282002200241286a36022020042001200241106a104621000b200241406b240020000bc50101017f230041106b220624000240200120024d0440200220044d0d012002200420051042000b230041306b220024002000200236020420002001360200200041146a41023602002000411c6a41023602002000412c6a410536020020004190920436021020004100360208200041053602242000200041206a3602182000200041046a36022820002000360220200041086a20051019000b200641086a2001200220031028200628020c21012000200628020836020020002001360204200641106a24000b980401047f230041106b22022400024002400240024002400240024002400240024002400240024020002d000041016b0e0b0102030405060708090a0b000b410121002001280200220341a2a00441062001280204220528020c22041100000d0b024020012d0018410471450440200341fc8b04410120041100000d0d200341c4a30441052004110000450d010c0d0b200341fa8b04410220041100000d0c2002200536020420022003360200200241013a000f20022002410f6a360208200241c4a304410510470d0c200241f88b04410210470d0c0b200341d18a044101200411000021000c0b0b20012802004195a004410d200128020428020c11000021000c0a0b20012802004187a004410e200128020428020c11000021000c090b200128020041fc9f04410b200128020428020c11000021000c080b200128020041e29f04411a200128020428020c11000021000c070b200128020041d49f04410e200128020428020c11000021000c060b200128020041c49f044110200128020428020c11000021000c050b200128020041b89f04410c200128020428020c11000021000c040b200128020041ad9f04410b200128020428020c11000021000c030b200128020041a69f044107200128020428020c11000021000c020b200128020041979f04410f200128020428020c11000021000c010b200128020041849f044113200128020428020c11000021000b200241106a240020000b14002000200120022003419ca20441b0a20410530b2800200120024d04402000200220016b3602042000200120036a3602000f0b200541212004100b000b7301017f230041306b220424002004200136020420042000360200200441146a41023602002004411c6a41023602002004412c6a41053602002004200336021020044100360208200441053602242004200441206a3602182004200441046a36022820042004360220200441086a20021019000b0b8a240300418080040ba904617474656d707420746f2073756274726163742077697468206f766572666c6f77636f756c64206e6f742070726f7065726c79206465636f64652073746f7261676520656e7472792f55736572732f7061726974792f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f696e6b5f73746f726167652d332e342e302f7372632f7472616974732f6d6f642e72730000004800010061000000a20000000a00000073746f7261676520656e7472792077617320656d707479004800010061000000a30000000a0000002f55736572732f7061726974792f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f696e6b5f656e762d332e342e302f7372632f656e67696e652f6f6e5f636861696e2f696d706c732e7273e4000100680000009a00000030000000e4000100680000009f0000002e00000000000000617474656d707420746f206164642077697468206f766572666c6f770900000001000000010000000a000000656e636f756e746572656420756e6578706563746564206572726f729c0101001c000000e400010068000000f600000017000000400e010069000000b800000009000000466c69707065723a3a496e6372656d656e7465642f55736572732f7061726974792f436f64652f3466756e2f666c69707065722f6c69622e72730000f40101002600000010000000050041cc84040b95176469737061746368696e6720696e6b2120636f6e7374727563746f72206661696c65643a200000004c020100250000006469737061746368696e6720696e6b21206d657373616765206661696c65643a200000007c02010021000000f401010026000000630000000d0000000900000004000000040000000b0000000c0000000d000000617474656d707420746f206164642077697468206f766572666c6f7700000000617474656d707420746f206d756c7469706c792077697468206f766572666c6f770000000900000000000000010000000e0000002f55736572732f7061726974792f2e7275737475702f746f6f6c636861696e732f6e696768746c792d616172636836342d6170706c652d64617277696e2f6c69622f727573746c69622f7372632f727573742f6c6962726172792f616c6c6f632f7372632f7261775f7665632e727300240301006f0000008a0100001c0000006361706163697479206f766572666c6f77000000a403010011000000240301006f00000006020000050000006120666f726d617474696e6720747261697420696d706c656d656e746174696f6e2072657475726e656420616e206572726f722f55736572732f7061726974792f2e7275737475702f746f6f6c636861696e732f6e696768746c792d616172636836342d6170706c652d64617277696e2f6c69622f727573746c69622f7372632f727573742f6c6962726172792f616c6c6f632f7372632f666d742e72730000030401006b00000064020000200000002f55736572732f7061726974792f2e7275737475702f746f6f6c636861696e732f6e696768746c792d616172636836342d6170706c652d64617277696e2f6c69622f727573746c69622f7372632f727573742f6c6962726172792f616c6c6f632f7372632f7665632f6d6f642e727300800401006f000000300700000d000000800401006f0000009e07000009000000617474656d707420746f206164642077697468206f766572666c6f7700000000617474656d707420746f2073756274726163742077697468206f766572666c6f7729696e646578206f7574206f6620626f756e64733a20746865206c656e20697320206275742074686520696e64657820697320520501002000000072050100120000003a0000002810010000000000940501000100000094050100010000000900000000000000010000000f00000070616e69636b65642061742027272c20cc05010001000000cd050100030000003a2000002810010000000000e005010002000000202020202c0a280a282f55736572732f7061726974792f2e7275737475702f746f6f6c636861696e732f6e696768746c792d616172636836342d6170706c652d64617277696e2f6c69622f727573746c69622f7372632f727573742f6c6962726172792f636f72652f7372632f666d742f6e756d2e727330303031303230333034303530363037303830393130313131323133313431353136313731383139323032313232323332343235323632373238323933303331333233333334333533363337333833393430343134323433343434353436343734383439353035313532353335343535353635373538353936303631363236333634363536363637363836393730373137323733373437353736373737383739383038313832383338343835383638373838383939303931393239333934393539363937393839392f55736572732f7061726974792f2e7275737475702f746f6f6c636861696e732f6e696768746c792d616172636836342d6170706c652d64617277696e2f6c69622f727573746c69622f7372632f727573742f6c6962726172792f636f72652f7372632f666d742f6d6f642e7273000000330701006e0000005d0500000d000000330701006e000000ed050000380000002f55736572732f7061726974792f2e7275737475702f746f6f6c636861696e732f6e696768746c792d616172636836342d6170706c652d64617277696e2f6c69622f727573746c69622f7372632f727573742f6c6962726172792f636f72652f7372632f736c6963652f6d656d6368722e727300c4070100730000004e0000002f000000c4070100730000005a0000001f000000c4070100730000006300000009000000c4070100730000006800000027000000c407010073000000680000003e00000072616e676520737461727420696e64657820206f7574206f662072616e676520666f7220736c696365206f66206c656e6774682088080100120000009a0801002200000072616e676520656e6420696e64657820cc080100100000009a08010022000000736c69636520696e64657820737461727473206174202062757420656e64732061742000ec08010016000000020901000d0000002f55736572732f7061726974792f2e7275737475702f746f6f6c636861696e732f6e696768746c792d616172636836342d6170706c652d64617277696e2f6c69622f727573746c69622f7372632f727573742f6c6962726172792f636f72652f7372632f736c6963652f697465722e72730000002009010071000000c4050000250000002f55736572732f7061726974792f2e7275737475702f746f6f6c636861696e732f6e696768746c792d616172636836342d6170706c652d64617277696e2f6c69622f727573746c69622f7372632f727573742f6c6962726172792f636f72652f7372632f736c6963652f6d6f642e7273a409010070000000f30300002f000000a409010070000000d30800001e000000736f7572636520736c696365206c656e67746820282920646f6573206e6f74206d617463682064657374696e6174696f6e20736c696365206c656e6774682028340a010015000000490a01002b00000051050100010000002f55736572732f7061726974792f2e7275737475702f746f6f6c636861696e732f6e696768746c792d616172636836342d6170706c652d64617277696e2f6c69622f727573746c69622f7372632f727573742f6c6962726172792f636f72652f7372632f7374722f636f756e742e72738c0a01007000000047000000150000008c0a01007000000054000000110000008c0a0100700000005a000000090000008c0a01007000000064000000110000008c0a010070000000660000000d0000002f55736572732f7061726974792f2e7275737475702f746f6f6c636861696e732f6e696768746c792d616172636836342d6170706c652d64617277696e2f6c69622f727573746c69622f7372632f727573742f6c6962726172792f636f72652f7372632f7374722f697465722e7273004c0b01006f00000091000000110000004c0b01006f0000004c0200003c0000002f55736572732f7061726974792f2e7275737475702f746f6f6c636861696e732f6e696768746c792d616172636836342d6170706c652d64617277696e2f6c69622f727573746c69622f7372632f727573742f6c6962726172792f636f72652f7372632f7374722f7472616974732e7273000000dc0b010071000000ca000000130000002f55736572732f7061726974792f2e7275737475702f746f6f6c636861696e732f6e696768746c792d616172636836342d6170706c652d64617277696e2f6c69622f727573746c69622f7372632f727573742f6c6962726172792f636f72652f7372632f7374722f7061747465726e2e72730000600c010072000000a101000047000000600c010072000000b401000020000000600c010072000000b401000011000000600c010072000000b8010000260000002f55736572732f7061726974792f2e7275737475702f746f6f6c636861696e732f6e696768746c792d616172636836342d6170706c652d64617277696e2f6c69622f727573746c69622f7372632f727573742f6c6962726172792f636f72652f7372632f697465722f7472616974732f616363756d2e7273140d0100780000009500000001000000fd0501006e000000cd01000005000000a810010072000000900100004f00000000000000617474656d707420746f2073756274726163742077697468206f766572666c6f770041f09b040bb308617474656d707420746f206164642077697468206f766572666c6f77617373657274696f6e206661696c65643a206d6964203c3d2073656c662e6c656e28290a28100100000000002f0e0100010000002f55736572732f7061726974792f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f696e6b5f656e762d332e342e302f7372632f656e67696e652f6f6e5f636861696e2f6275666665722e7273000000400e010069000000580000001c000000400e0100690000005800000009000000400e0100690000005800000031000000400e0100690000006300000009000000400e010069000000810000001a000000400e0100690000008b000000210000002f55736572732f7061726974792f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f696e6b5f656e762d332e342e302f7372632f656e67696e652f6f6e5f636861696e2f6578742e727300000c0f0100660000008c0100001400000045636473615265636f766572794661696c65644c6f6767696e6744697361626c6564556e6b6e6f776e4e6f7443616c6c61626c65436f64654e6f74466f756e645f456e646f776d656e74546f6f4c6f775472616e736665724661696c65645f42656c6f7753756273697374656e63655468726573686f6c644b65794e6f74466f756e6443616c6c6565526576657274656443616c6c6565547261707065644465636f646528100100000000007061696420616e20756e70617961626c65206d657373616765636f756c64206e6f74207265616420696e707574756e61626c6520746f206465636f646520696e707574656e636f756e746572656420756e6b6e6f776e2073656c6563746f72756e61626c6520746f206465636f64652073656c6563746f722f55736572732f7061726974792f2e7275737475702f746f6f6c636861696e732f6e696768746c792d616172636836342d6170706c652d64617277696e2f6c69622f727573746c69622f7372632f727573742f6c6962726172792f636f72652f7372632f736c6963652f696e6465782e72730000a810010072000000820100004700000000000000617474656d707420746f2073756274726163742077697468206f766572666c6f772f55736572732f7061726974792f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f7061726974792d7363616c652d636f6465632d332e322e312f7372632f636f6465632e727351110100630000007a0000000e0000004572726f72000000000000000100000002000000030000000400000005000000060000000700000008000000090000000c0000000b000000190000001c0000001600000014000000190000008f100100731001005d10010049100100301001"},"contract":{"name":"flipper","version":"0.1.0","authors":["[your_name] <[your_email]>"]},"V3":{"spec":{"constructors":[{"args":[{"label":"init_value","type":{"displayName":["bool"],"type":0}}],"docs":["Constructor that initializes the `bool` value to the given `init_value`."],"label":"new","payable":false,"selector":"0x9bae9d5e"},{"args":[],"docs":["Constructor that initializes the `bool` value to `false`.","","Constructors can delegate to other constructors."],"label":"default","payable":false,"selector":"0xed4b9d1b"}],"docs":[],"events":[{"args":[{"docs":[],"indexed":false,"label":"from","type":{"displayName":["Option"],"type":5}},{"docs":[],"indexed":false,"label":"count","type":{"displayName":["i32"],"type":1}}],"docs":[" Defines an event that is emitted"," every time inc is invoked."],"label":"Incremented"}],"messages":[{"args":[],"docs":[" A message that can be called on instantiated contracts."," This one flips the value of the stored `bool` from `true`"," to `false` and vice versa."],"label":"flip","mutates":true,"payable":false,"returnType":null,"selector":"0x633aa551"},{"args":[],"docs":[" Simply returns the current value of our `bool`."],"label":"get","mutates":false,"payable":false,"returnType":{"displayName":["bool"],"type":0},"selector":"0x2f865bd9"},{"args":[{"label":"a","type":{"displayName":["u32"],"type":2}},{"label":"b","type":{"displayName":["bool"],"type":0}}],"docs":[" multiple arg method returning a tuple."],"label":"method_returning_tuple","mutates":false,"payable":false,"returnType":{"displayName":[],"type":3},"selector":"0xdb48790e"},{"args":[{"label":"a","type":{"displayName":["u32"],"type":2}},{"label":"b","type":{"displayName":["bool"],"type":0}}],"docs":[" multiple arg method returning a struct."],"label":"method_returning_struct","mutates":false,"payable":false,"returnType":{"displayName":["M2"],"type":4},"selector":"0x5cb3e2d0"},{"args":[],"docs":[" get the current count."],"label":"get_count","mutates":false,"payable":false,"returnType":{"displayName":["i32"],"type":1},"selector":"0xbb20003a"},{"args":[],"docs":[" increment current count by 1"],"label":"inc","mutates":true,"payable":false,"returnType":null,"selector":"0x1d32619f"},{"args":[],"docs":[" decrement current count by 1"],"label":"dec","mutates":true,"payable":false,"returnType":null,"selector":"0xb5d7b4f0"},{"args":[{"label":"n","type":{"displayName":["i32"],"type":1}}],"docs":[" increment current count by n"],"label":"inc_by","mutates":true,"payable":false,"returnType":null,"selector":"0xfe5bd8ea"},{"args":[{"label":"n","type":{"displayName":["i32"],"type":1}}],"docs":[" increment current count by n and emit an event"],"label":"inc_by_with_event","mutates":true,"payable":false,"returnType":null,"selector":"0xd54ee71c"}]},"storage":{"struct":{"fields":[{"layout":{"cell":{"key":"0x0000000000000000000000000000000000000000000000000000000000000000","ty":0}},"name":"value"},{"layout":{"cell":{"key":"0x0100000000000000000000000000000000000000000000000000000000000000","ty":1}},"name":"count"}]}},"types":[{"id":0,"type":{"def":{"primitive":"bool"}}},{"id":1,"type":{"def":{"primitive":"i32"}}},{"id":2,"type":{"def":{"primitive":"u32"}}},{"id":3,"type":{"def":{"tuple":[2,0]}}},{"id":4,"type":{"def":{"composite":{"fields":[{"name":"a","type":2,"typeName":"u32"},{"name":"b","type":0,"typeName":"bool"}]}},"path":["flipper","flipper","M2"]}},{"id":5,"type":{"def":{"variant":{"variants":[{"index":0,"name":"None"},{"fields":[{"type":6}],"index":1,"name":"Some"}]}},"params":[{"name":"T","type":6}],"path":["Option"]}},{"id":6,"type":{"def":{"composite":{"fields":[{"type":7,"typeName":"[u8; 32]"}]}},"path":["ink_env","types","AccountId"]}},{"id":7,"type":{"def":{"array":{"len":32,"type":8}}}},{"id":8,"type":{"def":{"primitive":"u8"}}}]}} \ No newline at end of file diff --git a/examples/smart_contract/flipper.wasm b/examples/smart_contract/flipper.wasm index 592ae8515270a3b382919338848f2a06b58934d9..853e9eb999e81d075afd88be7decb9f947b47b2f 100644 GIT binary patch delta 6857 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 delta 5071 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 diff --git a/examples/smart_contract/metadata.json b/examples/smart_contract/metadata.json index b3d0b6ac3..3c897ad5d 100644 --- a/examples/smart_contract/metadata.json +++ b/examples/smart_contract/metadata.json @@ -1,6 +1,6 @@ { "source": { - "hash": "0xa64fbd08bc40eb972efb18c71ac812bd8219e9fd16b975f9ec070ce96ab32156", + "hash": "0x1e3986af05daee058d114887d78d251e7bad3700b7e5aa01741572162d7b3d85", "language": "ink! 3.4.0", "compiler": "rustc 1.68.0-nightly" }, @@ -46,7 +46,39 @@ } ], "docs": [], - "events": [], + "events": [ + { + "args": [ + { + "docs": [], + "indexed": false, + "label": "from", + "type": { + "displayName": [ + "Option" + ], + "type": 5 + } + }, + { + "docs": [], + "indexed": false, + "label": "count", + "type": { + "displayName": [ + "i32" + ], + "type": 1 + } + } + ], + "docs": [ + " Defines an event that is emitted", + " every time inc is invoked." + ], + "label": "Incremented" + } + ], "messages": [ { "args": [], @@ -99,16 +131,16 @@ } ], "docs": [ - " multiple arg method1." + " multiple arg method returning a tuple." ], - "label": "m1", + "label": "method_returning_tuple", "mutates": false, "payable": false, "returnType": { "displayName": [], "type": 3 }, - "selector": "0xfa2cbe71" + "selector": "0xdb48790e" }, { "args": [ @@ -132,9 +164,9 @@ } ], "docs": [ - " multiple arg method2." + " multiple arg method returning a struct." ], - "label": "m2", + "label": "method_returning_struct", "mutates": false, "payable": false, "returnType": { @@ -143,7 +175,7 @@ ], "type": 4 }, - "selector": "0x25f9a609" + "selector": "0x5cb3e2d0" }, { "args": [], @@ -203,6 +235,27 @@ "payable": false, "returnType": null, "selector": "0xfe5bd8ea" + }, + { + "args": [ + { + "label": "n", + "type": { + "displayName": [ + "i32" + ], + "type": 1 + } + } + ], + "docs": [ + " increment current count by n and emit an event" + ], + "label": "inc_by_with_event", + "mutates": true, + "payable": false, + "returnType": null, + "selector": "0xd54ee71c" } ] }, @@ -291,6 +344,78 @@ "M2" ] } + }, + { + "id": 5, + "type": { + "def": { + "variant": { + "variants": [ + { + "index": 0, + "name": "None" + }, + { + "fields": [ + { + "type": 6 + } + ], + "index": 1, + "name": "Some" + } + ] + } + }, + "params": [ + { + "name": "T", + "type": 6 + } + ], + "path": [ + "Option" + ] + } + }, + { + "id": 6, + "type": { + "def": { + "composite": { + "fields": [ + { + "type": 7, + "typeName": "[u8; 32]" + } + ] + } + }, + "path": [ + "ink_env", + "types", + "AccountId" + ] + } + }, + { + "id": 7, + "type": { + "def": { + "array": { + "len": 32, + "type": 8 + } + } + } + }, + { + "id": 8, + "type": { + "def": { + "primitive": "u8" + } + } } ] } From 7eb2f31e18b9949d7c318f4a0fb20dcc04352c17 Mon Sep 17 00:00:00 2001 From: Matias Volpe Date: Thu, 15 Dec 2022 13:24:46 -0300 Subject: [PATCH 11/21] fix: message id type --- rpc/messages.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rpc/messages.ts b/rpc/messages.ts index c54efd3bd..6a50b813e 100644 --- a/rpc/messages.ts +++ b/rpc/messages.ts @@ -9,7 +9,7 @@ export interface EgressMessage extends JsonRpcVersionBearer { - id: string + id: string | number result: Result params?: never error?: never @@ -19,7 +19,7 @@ export interface ErrorMessage< Code extends number = number, Data = any, > extends JsonRpcVersionBearer { - id: string + id: string | number error: { code: Code message: string From d5b69bb974f05e0b846e95b985c88e45f9fd8cb3 Mon Sep 17 00:00:00 2001 From: Matias Volpe Date: Fri, 16 Dec 2022 09:12:21 -0300 Subject: [PATCH 12/21] feat: cache contract message and event codecs --- examples/smart_contract.ts | 91 ++++++++++++++++++++++---------------- 1 file changed, 54 insertions(+), 37 deletions(-) diff --git a/examples/smart_contract.ts b/examples/smart_contract.ts index 757a53cbd..40429fdf4 100644 --- a/examples/smart_contract.ts +++ b/examples/smart_contract.ts @@ -129,12 +129,17 @@ function getFilePath(relativeFilePath: string) { class SmartContract { readonly deriveCodec + readonly $events + readonly $messageByLabel constructor( readonly metadata: C.M.ContractMetadata, readonly contractAddress: Uint8Array, ) { this.deriveCodec = C.M.DeriveCodec(metadata.V3.types) + const [$messageByLabel, $events] = this.#getCodecs() + this.$events = $events + this.$messageByLabel = $messageByLabel } call( @@ -143,7 +148,7 @@ class SmartContract { args: Args, ) { const message = this.#getMessageByLabel(messageLabel)! - const [$args, $result] = this.#getMessageCodecs(message) + const [$args, $result] = this.#getMessageCodecByLabel(messageLabel) const data = $args.encode([U.hex.decode(message.selector), ...args]) const callData = U.hex.encode($contractsApiCallArgs.encode([ origin, @@ -159,9 +164,6 @@ class SmartContract { ) .next((encodedResponse) => { const response = $contractsApiCallResult.decode(U.hex.decode(encodedResponse)) - if (message.returnType === null) { - return undefined - } return $result.decode(response.result.data) }) } @@ -173,7 +175,7 @@ class SmartContract { sign: C.Z.$, ) { const message = this.#getMessageByLabel(messageLabel)! - const [$args, _, $events] = this.#getMessageCodecs(message) + const [$args, _] = this.#getMessageCodecByLabel(messageLabel) const data = $args.encode([U.hex.decode(message.selector), ...args]) const value = this.#preSubmitContractCallDryRunGasEstimate(origin, data) .next(({ gasRequired }) => { @@ -210,7 +212,7 @@ class SmartContract { .filter( (e) => e.event?.type === "Contracts" && e.event?.value?.type === "ContractEmitted", ) - .map((e) => $events.decode(e.event?.value.data)) + .map((e) => this.$events.decode(e.event?.value.data)) return [finalizedIn, events, contractEvents] }) } @@ -221,37 +223,6 @@ class SmartContract { return this.metadata.V3.spec.messages.find((c) => c.label === label) } - #getMessageCodecs( - message: C.M.ContractMetadata.Message, - ): [C.$.Codec, C.$.Codec, C.$.Codec] { - // TODO: cache on initialization - const argCodecs = [ - // message selector - C.$.sizedUint8Array(U.hex.decode(message.selector).length), - // message args - ...message.args.map((arg) => this.deriveCodec(arg.type.type)), - ] - // TODO: cache on initialization - const $result = message.returnType !== null - ? this.deriveCodec(message.returnType.type) - : C.$.constant(null) - // FIXME: this is not message specific - const $events = C.$.taggedUnion( - "type", - this.metadata.V3.spec.events - .map((e) => [ - e.label, - [ - "value", - C.$.tuple(...e.args - .map((a) => this.deriveCodec(a.type.type))), - ], - ]), - ) - // @ts-ignore ... - return [C.$.tuple(...argCodecs), $result, $events] - } - #preSubmitContractCallDryRunGasEstimate( origin: Uint8Array, data: Uint8Array, @@ -272,6 +243,52 @@ class SmartContract { return $contractsApiCallResult.decode(U.hex.decode(encodedResponse)) }) } + + #getCodecs() { + const $messageByLabel = this.metadata.V3.spec.messages.reduce( + (acc, message) => { + acc[message.label] = this.#getMessageCodecs(message) + return acc + }, + {} as Record, resultCodec: C.$.Codec]>, + ) + const $events = C.$.taggedUnion( + "type", + this.metadata.V3.spec.events + .map((e) => [ + e.label, + [ + "value", + C.$.tuple(...e.args + .map((a) => this.deriveCodec(a.type.type))), + ], + ]), + ) + return [$messageByLabel, $events] as [ + Record, resultCodec: C.$.Codec]>, + C.$.Codec, + ] + } + + #getMessageCodecs( + message: C.M.ContractMetadata.Message, + ): [argsCodec: C.$.Codec, resultCodec: C.$.Codec] { + const argCodecs = [ + // message selector + C.$.sizedUint8Array(U.hex.decode(message.selector).length), + // message args + ...message.args.map((arg) => this.deriveCodec(arg.type.type)), + ] + const $result = message.returnType !== null + ? this.deriveCodec(message.returnType.type) + : C.$.constant(null) + // @ts-ignore ... + return [C.$.tuple(...argCodecs), $result] + } + + #getMessageCodecByLabel(label: string) { + return this.$messageByLabel[label]! + } } const prefix = U.throwIfError(await ss58Prefix.run()) From 45d1477f27f82685cdc7747e9d9a06be0bb3424d Mon Sep 17 00:00:00 2001 From: Matias Volpe Date: Fri, 16 Dec 2022 16:54:09 -0300 Subject: [PATCH 13/21] feat: refactor smart contract example Co-authored-by: Harry Solovay --- cspell.json | 9 +- deps/std/encoding/base58.ts | 3 +- effects/contracts/instantiate.ts | 64 +++++++ effects/contracts/mod.ts | 1 + effects/mod.ts | 1 + examples/smart_contract.ts | 292 +++++++++++-------------------- 6 files changed, 175 insertions(+), 195 deletions(-) create mode 100644 effects/contracts/instantiate.ts create mode 100644 effects/contracts/mod.ts diff --git a/cspell.json b/cspell.json index 282c91603..b659c059d 100644 --- a/cspell.json +++ b/cspell.json @@ -10,14 +10,11 @@ ], "dictionaries": ["project-words"], "ignorePaths": [ - "**/mod.generated.js", - "**/mod_bg.wasm", - "Cargo.lock", - "deno.lock", + "**/*.wasm", "frame_metadata/raw_erc20_metadata.json", "target", "**/__snapshots__/*.snap", - "codegen/_output", - "examples/smart_contract" + "**/*.contract", + "examples/smart_contract/metadata.json" ] } diff --git a/deps/std/encoding/base58.ts b/deps/std/encoding/base58.ts index b2361fcb0..fbe18cd03 100644 --- a/deps/std/encoding/base58.ts +++ b/deps/std/encoding/base58.ts @@ -1,2 +1 @@ -// TODO: use std@0.168.0/encoding/base58.ts when https://github.com/denoland/deno_std/pull/2982 is released -export * from "https://raw.githubusercontent.com/denoland/deno_std/01696ce149463f498301782ac5e9ee322a86182c/encoding/base58.ts" +export * from "https://deno.land/std@0.168.0/encoding/base58.ts" diff --git a/effects/contracts/instantiate.ts b/effects/contracts/instantiate.ts new file mode 100644 index 000000000..622fd8157 --- /dev/null +++ b/effects/contracts/instantiate.ts @@ -0,0 +1,64 @@ +import * as Z from "../../deps/zones.ts" +import { + $contractsApiInstantiateArgs, + $contractsApiInstantiateResult, + ContractMetadata, +} from "../../frame_metadata/Contract.ts" +import { MultiAddress } from "../../frame_metadata/mod.ts" +import { Client } from "../../rpc/mod.ts" +import * as U from "../../util/mod.ts" +import { extrinsic } from "../extrinsic.ts" +import { state } from "../rpc_known_methods.ts" + +export interface InstantiateProps { + sender: MultiAddress + code: Uint8Array + constructorMetadata: ContractMetadata.Constructor + salt: Uint8Array +} + +export function instantiate>(client: Client_) { + return >(_props: Props) => { + const { code, constructorMetadata, sender } = _props as Z.Rec$Access + const value = Z.ls(_props.salt, instantiateGasEstimate(client)(_props), constructorMetadata) + .next(([salt, { gasRequired }, { selector }]) => { + // the contract address derived from the code hash and the salt + return { + type: "instantiateWithCode", + value: 0n, + gasLimit: gasRequired, + storageDepositLimit: undefined, + code, + data: U.hex.decode(selector), + salt, + } + }) + return extrinsic(client)({ + sender, + call: Z.rec({ type: "Contracts", value }), + }) + } +} + +export function instantiateGasEstimate>(client: Client_) { + return >(_props: Props) => { + const key = Z.rec(_props as Z.Rec$Access).next( + ({ code, constructorMetadata, sender, salt }) => { + return U.hex.encode($contractsApiInstantiateArgs.encode([ + sender.value!, // TODO: grab public key in cases where we're not accepting multi? + 0n, + undefined, + undefined, + { type: "Upload", value: code }, + U.hex.decode(constructorMetadata.selector), + salt, + ])) + }, + ) + return state + .call(client)("ContractsApi_instantiate", key) + .next((encodedResponse) => { + return $contractsApiInstantiateResult.decode(U.hex.decode(encodedResponse)) + }) + } +} diff --git a/effects/contracts/mod.ts b/effects/contracts/mod.ts new file mode 100644 index 000000000..5eaee97b9 --- /dev/null +++ b/effects/contracts/mod.ts @@ -0,0 +1 @@ +export * from "./instantiate.ts" diff --git a/effects/mod.ts b/effects/mod.ts index 8cfd4c3e5..bca36a484 100644 --- a/effects/mod.ts +++ b/effects/mod.ts @@ -1,5 +1,6 @@ export * from "./blockWatch.ts" export * from "./const.ts" +export * as contracts from "./contracts/mod.ts" export * from "./entryRead.ts" export * from "./entryWatch.ts" export * from "./events.ts" diff --git a/examples/smart_contract.ts b/examples/smart_contract.ts index 40429fdf4..3322355af 100644 --- a/examples/smart_contract.ts +++ b/examples/smart_contract.ts @@ -1,76 +1,21 @@ -import * as path from "http://localhost:5646/@local/deps/std/path.ts" import * as C from "http://localhost:5646/@local/mod.ts" import * as T from "http://localhost:5646/@local/test_util/mod.ts" import * as U from "http://localhost:5646/@local/util/mod.ts" -import { - $contractsApiCallArgs, - $contractsApiCallResult, - $contractsApiInstantiateArgs, - $contractsApiInstantiateResult, -} from "../frame_metadata/Contract.ts" +import { $contractsApiCallArgs, $contractsApiCallResult } from "../frame_metadata/Contract.ts" -const configFile = getFilePath("smart_contract/zombienet.toml") -const zombienet = await T.zombienet.start(configFile) -const client = zombienet.clients.byName["collator01"]! +// const configFile = getFilePath("smart_contract/zombienet.toml") +// const zombienet = await T.zombienet.start(configFile) +// const client = zombienet.clients.byName["collator01"]! +const client = C.polkadot -const contract = await getContract( - getFilePath("smart_contract/flipper.wasm"), - getFilePath("smart_contract/metadata.json"), -) - -const ss58Prefix = C.const(client)("System", "SS58Prefix").access("value") +const salt = Uint8Array.from(Array.from([0, 0, 0, 0]), () => Math.floor(Math.random() * 16)) -function instantiateContractTx() { - const constructor = findContractConstructorByLabel("default")! - const salt = Uint8Array.from(Array.from([0, 0, 0, 0]), () => Math.floor(Math.random() * 16)) - const value = C.Z.ls( - preSubmitContractInstantiateDryRunGasEstimate(constructor, contract.wasm, salt), - ss58Prefix, - ) - .next(([{ gasRequired, result: { accountId } }, prefix]) => { - // the contract address derived from the code hash and the salt - console.log("Derived contract address", U.ss58.encode(prefix, accountId)) - return { - type: "instantiateWithCode", - value: 0n, - gasLimit: gasRequired, - storageDepositLimit: undefined, - code: contract.wasm, - data: U.hex.decode(constructor.selector), - salt, - } - }) - const tx = C.extrinsic(client)({ - sender: T.alice.address, - call: C.Z.rec({ - type: "Contracts", - value, - }), - }) - .signed(T.alice.sign) - const finalizedIn = tx.watch(({ end }) => - (status) => { - if (typeof status !== "string" && (status.inBlock ?? status.finalized)) { - return end(status.inBlock ?? status.finalized) - } else if (C.rpc.known.TransactionStatus.isTerminal(status)) { - return end(new Error()) - } - return - } - ) - return C.events(tx, finalizedIn).next((events) => { - const extrinsicFailedEvent = events.find((e) => - e.event?.type === "System" && e.event?.value?.type === "ExtrinsicFailed" - ) - if (extrinsicFailedEvent) { - return new ExtrinsicFailed(extrinsicFailedEvent) - } - const event = events.find((e) => - e.event?.type === "Contracts" && e.event?.value?.type === "Instantiated" - ) - return event?.event?.value.contract as Uint8Array - }) -} +const [code, metadataRaw] = await Promise.all([ + await Deno.readFile("examples/smart_contract/flipper.wasm"), + await Deno.readTextFile("examples/smart_contract/metadata.json"), +]) +const metadata = C.M.ContractMetadata.normalize(JSON.parse(metadataRaw)) +const constructorMetadata = metadata.V3.spec.constructors.find((c) => c.label === "default")! class ExtrinsicFailed extends Error { override readonly name = "ExtrinsicFailedError" @@ -84,62 +29,73 @@ class ExtrinsicFailed extends Error { } } -function preSubmitContractInstantiateDryRunGasEstimate( - message: C.M.ContractMetadata.Constructor, - code: Uint8Array, - salt: Uint8Array, -) { - const key = U.hex.encode($contractsApiInstantiateArgs.encode([ - T.alice.publicKey, - 0n, - undefined, - undefined, - { type: "Upload", value: code }, - U.hex.decode(message.selector), - salt, - ])) - return C.state.call(client)( - "ContractsApi_instantiate", - key, - ) - .next((encodedResponse) => { - return $contractsApiInstantiateResult.decode(U.hex.decode(encodedResponse)) +const tx = C.contracts.instantiate(client)({ + code, + constructorMetadata, + salt, + sender: T.alice.address, +}).signed(T.alice.sign) +const finalizedIn = tx.watch(({ end }) => + (status) => { + if (typeof status !== "string" && (status.inBlock ?? status.finalized)) { + return end(status.inBlock ?? status.finalized) + } else if (C.rpc.known.TransactionStatus.isTerminal(status)) { + return end(new Error()) + } + return + } +) +const contractAddress = U.throwIfError( + await C + .events(tx, finalizedIn) + .next((events) => { + const extrinsicFailedEvent = events.find((e) => + e.event?.type === "System" && e.event?.value?.type === "ExtrinsicFailed" + ) + if (extrinsicFailedEvent) { + return new ExtrinsicFailed(extrinsicFailedEvent) + } + const event = events.find((e) => + e.event?.type === "Contracts" && e.event?.value?.type === "Instantiated" + ) + return event?.event?.value.contract as Uint8Array }) -} + .run(), +) -function findContractConstructorByLabel(label: string) { - return contract.metadata.V3.spec.constructors.find((c) => c.label === label) -} +// await zombienet.close() -async function getContract(wasmFile: string, metadataFile: string) { - const wasm = await Deno.readFile(wasmFile) - const metadata = C.M.ContractMetadata.normalize(JSON.parse( - await Deno.readTextFile(metadataFile), - )) - const deriveCodec = C.M.DeriveCodec(metadata.V3.types) - return { wasm, metadata, deriveCodec } +interface MessageCodecs { + $args: C.$.Codec<[Uint8Array, ...unknown[]]> + $result: C.$.Codec } -function getFilePath(relativeFilePath: string) { - return path.join( - path.dirname(path.fromFileUrl(import.meta.url)), - relativeFilePath, - ) -} - -class SmartContract { +class Contract> { readonly deriveCodec readonly $events readonly $messageByLabel constructor( + readonly client: Client, readonly metadata: C.M.ContractMetadata, readonly contractAddress: Uint8Array, ) { this.deriveCodec = C.M.DeriveCodec(metadata.V3.types) - const [$messageByLabel, $events] = this.#getCodecs() - this.$events = $events - this.$messageByLabel = $messageByLabel + this.$messageByLabel = metadata.V3.spec.messages.reduce>( + (acc, message) => { + acc[message.label] = this.#getMessageCodecs(message) + return acc + }, + {}, + ) + this.$events = C.$.taggedUnion( + "type", + metadata.V3.spec.events + .map((e) => [ + e.label, + ["value", C.$.tuple(...e.args.map((a) => this.deriveCodec(a.type.type)))], + ]), + ) } call( @@ -148,7 +104,7 @@ class SmartContract { args: Args, ) { const message = this.#getMessageByLabel(messageLabel)! - const [$args, $result] = this.#getMessageCodecByLabel(messageLabel) + const { $args, $result } = this.#getMessageCodecByLabel(messageLabel) const data = $args.encode([U.hex.decode(message.selector), ...args]) const callData = U.hex.encode($contractsApiCallArgs.encode([ origin, @@ -175,19 +131,33 @@ class SmartContract { sign: C.Z.$, ) { const message = this.#getMessageByLabel(messageLabel)! - const [$args, _] = this.#getMessageCodecByLabel(messageLabel) + const { $args } = this.#getMessageCodecByLabel(messageLabel) const data = $args.encode([U.hex.decode(message.selector), ...args]) - const value = this.#preSubmitContractCallDryRunGasEstimate(origin, data) - .next(({ gasRequired }) => { - return { - type: "call", - dest: C.MultiAddress.Id(this.contractAddress), - value: 0n, - data, - gasLimit: gasRequired, - storageDepositLimit: undefined, - } + const callData = U.hex.encode($contractsApiCallArgs.encode([ + origin, + this.contractAddress, + 0n, + undefined, + undefined, + data, + ])) + const estimate = C.state.call(client)( + "ContractsApi_call", + callData, + ) + .next((encodedResponse) => { + return $contractsApiCallResult.decode(U.hex.decode(encodedResponse)) }) + const value = estimate.next(({ gasRequired }) => { + return { + type: "call", + dest: C.MultiAddress.Id(this.contractAddress), + value: 0n, + data, + gasLimit: gasRequired, + storageDepositLimit: undefined, + } + }) const tx = C.extrinsic(client)({ sender: C.MultiAddress.Id(origin), call: C.Z.rec({ @@ -223,67 +193,18 @@ class SmartContract { return this.metadata.V3.spec.messages.find((c) => c.label === label) } - #preSubmitContractCallDryRunGasEstimate( - origin: Uint8Array, - data: Uint8Array, - ) { - const callData = U.hex.encode($contractsApiCallArgs.encode([ - origin, - this.contractAddress, - 0n, - undefined, - undefined, - data, - ])) - return C.state.call(client)( - "ContractsApi_call", - callData, - ) - .next((encodedResponse) => { - return $contractsApiCallResult.decode(U.hex.decode(encodedResponse)) - }) - } - - #getCodecs() { - const $messageByLabel = this.metadata.V3.spec.messages.reduce( - (acc, message) => { - acc[message.label] = this.#getMessageCodecs(message) - return acc - }, - {} as Record, resultCodec: C.$.Codec]>, - ) - const $events = C.$.taggedUnion( - "type", - this.metadata.V3.spec.events - .map((e) => [ - e.label, - [ - "value", - C.$.tuple(...e.args - .map((a) => this.deriveCodec(a.type.type))), - ], - ]), - ) - return [$messageByLabel, $events] as [ - Record, resultCodec: C.$.Codec]>, - C.$.Codec, - ] - } - - #getMessageCodecs( - message: C.M.ContractMetadata.Message, - ): [argsCodec: C.$.Codec, resultCodec: C.$.Codec] { - const argCodecs = [ - // message selector - C.$.sizedUint8Array(U.hex.decode(message.selector).length), - // message args - ...message.args.map((arg) => this.deriveCodec(arg.type.type)), - ] - const $result = message.returnType !== null - ? this.deriveCodec(message.returnType.type) - : C.$.constant(null) - // @ts-ignore ... - return [C.$.tuple(...argCodecs), $result] + #getMessageCodecs(message: C.M.ContractMetadata.Message): MessageCodecs { + return { + $args: C.$.tuple( + // message selector + C.$.sizedUint8Array(U.hex.decode(message.selector).length), + // message args + ...message.args.map((arg) => this.deriveCodec(arg.type.type)), + ), + $result: message.returnType !== null + ? this.deriveCodec(message.returnType.type) + : C.$.constant(null), + } } #getMessageCodecByLabel(label: string) { @@ -291,11 +212,10 @@ class SmartContract { } } -const prefix = U.throwIfError(await ss58Prefix.run()) -const contractAddress = U.throwIfError(await instantiateContractTx().run()) +const prefix = U.throwIfError(await C.const(client)("System", "SS58Prefix").access("value").run()) console.log("Deployed Contract address", U.ss58.encode(prefix, contractAddress)) -const flipperContract = new SmartContract(contract.metadata, contractAddress) +const flipperContract = new Contract(T.polkadot, metadata, contractAddress) console.log(".get", await flipperContract.call(T.alice.publicKey, "get", []).run()) console.log( "block hash and events", @@ -331,5 +251,3 @@ console.log( ".method_returning_struct(3,false)", await flipperContract.call(T.alice.publicKey, "method_returning_struct", [3, false]).run(), ) - -await zombienet.close() From 3d7e49421ea0bba9ca617745a39f3f5bc87ad4c8 Mon Sep 17 00:00:00 2001 From: Matias Volpe Date: Fri, 16 Dec 2022 17:16:21 -0300 Subject: [PATCH 14/21] feat: refactor Contract call, query and tx methods --- examples/smart_contract.ts | 104 +++++++++++++++++++------------------ 1 file changed, 53 insertions(+), 51 deletions(-) diff --git a/examples/smart_contract.ts b/examples/smart_contract.ts index 3322355af..9245cb639 100644 --- a/examples/smart_contract.ts +++ b/examples/smart_contract.ts @@ -1,12 +1,21 @@ +// This example requires zombienet-macos/zombienet-linux, polkadot and polkadot-parachain binaries in the PATH + +import * as path from "http://localhost:5646/@local/deps/std/path.ts" import * as C from "http://localhost:5646/@local/mod.ts" import * as T from "http://localhost:5646/@local/test_util/mod.ts" import * as U from "http://localhost:5646/@local/util/mod.ts" -import { $contractsApiCallArgs, $contractsApiCallResult } from "../frame_metadata/Contract.ts" - -// const configFile = getFilePath("smart_contract/zombienet.toml") -// const zombienet = await T.zombienet.start(configFile) -// const client = zombienet.clients.byName["collator01"]! -const client = C.polkadot +import { + $contractsApiCallArgs, + $contractsApiCallResult, + ContractMetadata, +} from "../frame_metadata/Contract.ts" + +const configFile = path.join( + path.dirname(path.fromFileUrl(import.meta.url)), + "smart_contract/zombienet.toml", +) +const zombienet = await T.zombienet.start(configFile) +const client = zombienet.clients.byName["collator01"]! const salt = Uint8Array.from(Array.from([0, 0, 0, 0]), () => Math.floor(Math.random() * 16)) @@ -63,8 +72,6 @@ const contractAddress = U.throwIfError( .run(), ) -// await zombienet.close() - interface MessageCodecs { $args: C.$.Codec<[Uint8Array, ...unknown[]]> $result: C.$.Codec @@ -98,30 +105,16 @@ class Contract> { ) } - call( + query( origin: Uint8Array, messageLabel: string, args: Args, ) { const message = this.#getMessageByLabel(messageLabel)! - const { $args, $result } = this.#getMessageCodecByLabel(messageLabel) - const data = $args.encode([U.hex.decode(message.selector), ...args]) - const callData = U.hex.encode($contractsApiCallArgs.encode([ - origin, - this.contractAddress, - 0n, - undefined, - undefined, - data, - ])) - return C.state.call(client)( - "ContractsApi_call", - callData, + const { $result } = this.#getMessageCodecByLabel(messageLabel) + return this.#call(origin, message, args).access("result").next((result) => + $result.decode(result.data) ) - .next((encodedResponse) => { - const response = $contractsApiCallResult.decode(U.hex.decode(encodedResponse)) - return $result.decode(response.result.data) - }) } tx( @@ -133,22 +126,8 @@ class Contract> { const message = this.#getMessageByLabel(messageLabel)! const { $args } = this.#getMessageCodecByLabel(messageLabel) const data = $args.encode([U.hex.decode(message.selector), ...args]) - const callData = U.hex.encode($contractsApiCallArgs.encode([ - origin, - this.contractAddress, - 0n, - undefined, - undefined, - data, - ])) - const estimate = C.state.call(client)( - "ContractsApi_call", - callData, - ) - .next((encodedResponse) => { - return $contractsApiCallResult.decode(U.hex.decode(encodedResponse)) - }) - const value = estimate.next(({ gasRequired }) => { + const gasRequired = this.#call(origin, message, args).access("gasRequired") + const value = gasRequired.next((gasRequired) => { return { type: "call", dest: C.MultiAddress.Id(this.contractAddress), @@ -176,17 +155,38 @@ class Contract> { return } ) + // FIXME: extract into a contract effect util return C.Z.ls(finalizedIn, C.events(tx, finalizedIn)) .next(([finalizedIn, events]) => { const contractEvents: any[] = events - .filter( - (e) => e.event?.type === "Contracts" && e.event?.value?.type === "ContractEmitted", + .filter((e) => + e.event?.type === "Contracts" && e.event?.value?.type === "ContractEmitted" ) .map((e) => this.$events.decode(e.event?.value.data)) return [finalizedIn, events, contractEvents] }) } + #call( + origin: Uint8Array, + message: ContractMetadata.Message, + args: Args, + ) { + const { $args } = this.#getMessageCodecByLabel(message.label) + const data = $args.encode([U.hex.decode(message.selector), ...args]) + const callData = U.hex.encode($contractsApiCallArgs.encode([ + origin, + this.contractAddress, + 0n, + undefined, + undefined, + data, + ])) + return C.state + .call(client)("ContractsApi_call", callData) + .next((encodedResponse) => $contractsApiCallResult.decode(U.hex.decode(encodedResponse))) + } + // TODO: codegen each contract message as a method #getMessageByLabel(label: string) { @@ -216,13 +216,13 @@ const prefix = U.throwIfError(await C.const(client)("System", "SS58Prefix").acce console.log("Deployed Contract address", U.ss58.encode(prefix, contractAddress)) const flipperContract = new Contract(T.polkadot, metadata, contractAddress) -console.log(".get", await flipperContract.call(T.alice.publicKey, "get", []).run()) +console.log(".get", await flipperContract.query(T.alice.publicKey, "get", []).run()) console.log( "block hash and events", U.throwIfError(await flipperContract.tx(T.alice.publicKey, "flip", [], T.alice.sign).run())[0], ) -console.log(".get", await flipperContract.call(T.alice.publicKey, "get", []).run()) -console.log(".get_count", await flipperContract.call(T.alice.publicKey, "get_count", []).run()) +console.log(".get", await flipperContract.query(T.alice.publicKey, "get", []).run()) +console.log(".get_count", await flipperContract.query(T.alice.publicKey, "get_count", []).run()) console.log( ".inc block hash", U.throwIfError(await flipperContract.tx(T.alice.publicKey, "inc", [], T.alice.sign).run())[0], @@ -231,12 +231,12 @@ console.log( ".inc block hash", U.throwIfError(await flipperContract.tx(T.alice.publicKey, "inc", [], T.alice.sign).run())[0], ) -console.log(".get_count", await flipperContract.call(T.alice.publicKey, "get_count", []).run()) +console.log(".get_count", await flipperContract.query(T.alice.publicKey, "get_count", []).run()) console.log( ".inc_by(3) block hash", U.throwIfError(await flipperContract.tx(T.alice.publicKey, "inc_by", [3], T.alice.sign).run())[0], ) -console.log(".get_count", await flipperContract.call(T.alice.publicKey, "get_count", []).run()) +console.log(".get_count", await flipperContract.query(T.alice.publicKey, "get_count", []).run()) console.log( ".inc_by_with_event(3) contract events", U.throwIfError( @@ -245,9 +245,11 @@ console.log( ) console.log( ".method_returning_tuple(2,true)", - await flipperContract.call(T.alice.publicKey, "method_returning_tuple", [2, true]).run(), + await flipperContract.query(T.alice.publicKey, "method_returning_tuple", [2, true]).run(), ) console.log( ".method_returning_struct(3,false)", - await flipperContract.call(T.alice.publicKey, "method_returning_struct", [3, false]).run(), + await flipperContract.query(T.alice.publicKey, "method_returning_struct", [3, false]).run(), ) + +await zombienet.close() From ba83409445d95bc1ee93aec5f86a62b3e8495cdc Mon Sep 17 00:00:00 2001 From: Matias Volpe Date: Mon, 19 Dec 2022 12:53:00 -0300 Subject: [PATCH 15/21] feat: add contract call effect --- effects/contracts/call.ts | 152 +++++++++++++++++++++++++++++++ effects/contracts/instantiate.ts | 4 +- effects/contracts/mod.ts | 1 + examples/smart_contract.ts | 140 ++++++++-------------------- 4 files changed, 192 insertions(+), 105 deletions(-) create mode 100644 effects/contracts/call.ts diff --git a/effects/contracts/call.ts b/effects/contracts/call.ts new file mode 100644 index 000000000..092af7ac9 --- /dev/null +++ b/effects/contracts/call.ts @@ -0,0 +1,152 @@ +import * as $ from "../../deps/scale.ts" +import * as Z from "../../deps/zones.ts" +import { + $contractsApiCallArgs, + $contractsApiCallResult, + ContractMetadata, +} from "../../frame_metadata/Contract.ts" +import { DeriveCodec, MultiAddress } from "../../frame_metadata/mod.ts" +import { Client } from "../../rpc/mod.ts" +import * as U from "../../util/mod.ts" +import { extrinsic } from "../extrinsic.ts" +import { state } from "../rpc_known_methods.ts" + +export interface CallProps { + sender: MultiAddress + contractAddress: Uint8Array + contractMetadata: ContractMetadata + message: ContractMetadata.Message + args: any[] +} + +export function call>(client: Client_) { + return >(_props: Props) => { + const { + sender, + contractAddress, + contractMetadata, + message, + args, + } = _props as Z.Rec$Access + const $message_ = $message(contractMetadata, message) + const data = Z.ls($message_, message, args).next(([{ $args }, message, args]) => { + return $args.encode([U.hex.decode(message.selector), ...args]) + }) + return Z.ls( + stateContractsApiCall(client)({ + sender, + contractAddress, + data, + }), + $message_, + ) + .next(([result, { $result }]) => { + return $result.decode(result.result.data) + }) + } +} + +export interface CallTxProps { + sender: MultiAddress + contractAddress: Uint8Array + value?: bigint + contractMetadata: ContractMetadata + message: ContractMetadata.Message + args: any[] +} + +export function callTx>(client: Client_) { + return >(_props: Props) => { + const { + sender, + contractAddress, + value, + contractMetadata, + message, + args, + } = _props as Z.Rec$Access + const $message_ = $message(contractMetadata, message) + const data = Z.ls($message_, message, args).next(([{ $args }, message, args]) => { + return $args.encode([U.hex.decode(message.selector), ...args]) + }) + const txValue = Z.ls( + stateContractsApiCall(client)({ + sender, + contractAddress, + value, + data, + }), + contractAddress, + value, + data, + ) + .next(([{ gasRequired }, contractAddress, value, data]) => { + return { + type: "call", + dest: MultiAddress.Id(contractAddress), + value: value ?? 0n, + data, + gasLimit: gasRequired, + storageDepositLimit: undefined, + } + }) + return extrinsic(client)({ + sender, + call: Z.rec({ type: "Contracts", value: txValue }), + }) + } +} + +export interface ContractsApiCallProps { + sender: MultiAddress + contractAddress: Uint8Array + value?: bigint + data: Uint8Array +} + +export function stateContractsApiCall>(client: Client_) { + return >(_props: Props) => { + const key = Z.rec(_props as Z.Rec$Access).next( + ({ sender, contractAddress, value, data }) => { + return U.hex.encode($contractsApiCallArgs.encode([ + sender.value!, // TODO: grab public key in cases where we're not accepting multi? + contractAddress, + value ?? 0n, + undefined, + undefined, + data, + ])) + }, + ) + return state + .call(client)("ContractsApi_call", key) + .next((result) => { + return $contractsApiCallResult.decode(U.hex.decode(result)) + }) + } +} + +interface MessageCodecs { + $args: $.Codec<[Uint8Array, ...unknown[]]> + $result: $.Codec +} + +function $message( + metadata: Z.$, + message: Z.$, +): Z.$ { + return Z.ls(metadata, message).next(([metadata, message]) => { + const deriveCodec = DeriveCodec(metadata.V3.types) + return { + $args: $.tuple( + // message selector + $.sizedUint8Array(U.hex.decode(message.selector).length), + // message args + ...message.args.map((arg) => deriveCodec(arg.type.type)), + ), + $result: message.returnType !== null + ? deriveCodec(message.returnType.type) + : $.constant(null), + } + }) +} diff --git a/effects/contracts/instantiate.ts b/effects/contracts/instantiate.ts index 622fd8157..90ff31a33 100644 --- a/effects/contracts/instantiate.ts +++ b/effects/contracts/instantiate.ts @@ -57,8 +57,6 @@ export function instantiateGasEstimate>(client: ) return state .call(client)("ContractsApi_instantiate", key) - .next((encodedResponse) => { - return $contractsApiInstantiateResult.decode(U.hex.decode(encodedResponse)) - }) + .next((result) => $contractsApiInstantiateResult.decode(U.hex.decode(result))) } } diff --git a/effects/contracts/mod.ts b/effects/contracts/mod.ts index 5eaee97b9..a4a0a9be5 100644 --- a/effects/contracts/mod.ts +++ b/effects/contracts/mod.ts @@ -1 +1,2 @@ +export * from "./call.ts" export * from "./instantiate.ts" diff --git a/examples/smart_contract.ts b/examples/smart_contract.ts index 9245cb639..b8a299d09 100644 --- a/examples/smart_contract.ts +++ b/examples/smart_contract.ts @@ -4,11 +4,6 @@ import * as path from "http://localhost:5646/@local/deps/std/path.ts" import * as C from "http://localhost:5646/@local/mod.ts" import * as T from "http://localhost:5646/@local/test_util/mod.ts" import * as U from "http://localhost:5646/@local/util/mod.ts" -import { - $contractsApiCallArgs, - $contractsApiCallResult, - ContractMetadata, -} from "../frame_metadata/Contract.ts" const configFile = path.join( path.dirname(path.fromFileUrl(import.meta.url)), @@ -72,77 +67,53 @@ const contractAddress = U.throwIfError( .run(), ) -interface MessageCodecs { - $args: C.$.Codec<[Uint8Array, ...unknown[]]> - $result: C.$.Codec -} - class Contract> { - readonly deriveCodec readonly $events - readonly $messageByLabel constructor( readonly client: Client, - readonly metadata: C.M.ContractMetadata, + readonly contractMetadata: C.M.ContractMetadata, readonly contractAddress: Uint8Array, ) { - this.deriveCodec = C.M.DeriveCodec(metadata.V3.types) - this.$messageByLabel = metadata.V3.spec.messages.reduce>( - (acc, message) => { - acc[message.label] = this.#getMessageCodecs(message) - return acc - }, - {}, - ) + const deriveCodec = C.M.DeriveCodec(contractMetadata.V3.types) this.$events = C.$.taggedUnion( "type", - metadata.V3.spec.events + contractMetadata.V3.spec.events .map((e) => [ e.label, - ["value", C.$.tuple(...e.args.map((a) => this.deriveCodec(a.type.type)))], + ["value", C.$.tuple(...e.args.map((a) => deriveCodec(a.type.type)))], ]), ) } - query( - origin: Uint8Array, + call( + sender: C.MultiAddress, messageLabel: string, args: Args, ) { const message = this.#getMessageByLabel(messageLabel)! - const { $result } = this.#getMessageCodecByLabel(messageLabel) - return this.#call(origin, message, args).access("result").next((result) => - $result.decode(result.data) - ) + return C.contracts.call(client)({ + sender, + contractAddress: this.contractAddress, + contractMetadata: this.contractMetadata, + message, + args, + }) } - tx( - origin: Uint8Array, + callTx( + sender: C.MultiAddress, messageLabel: string, args: Args, sign: C.Z.$, ) { const message = this.#getMessageByLabel(messageLabel)! - const { $args } = this.#getMessageCodecByLabel(messageLabel) - const data = $args.encode([U.hex.decode(message.selector), ...args]) - const gasRequired = this.#call(origin, message, args).access("gasRequired") - const value = gasRequired.next((gasRequired) => { - return { - type: "call", - dest: C.MultiAddress.Id(this.contractAddress), - value: 0n, - data, - gasLimit: gasRequired, - storageDepositLimit: undefined, - } - }) - const tx = C.extrinsic(client)({ - sender: C.MultiAddress.Id(origin), - call: C.Z.rec({ - type: "Contracts", - value, - }), + const tx = C.contracts.callTx(client)({ + sender, + contractAddress: this.contractAddress, + contractMetadata: this.contractMetadata, + message, + args, }) .signed(sign) const finalizedIn = tx.watch(({ end }) => @@ -155,7 +126,6 @@ class Contract> { return } ) - // FIXME: extract into a contract effect util return C.Z.ls(finalizedIn, C.events(tx, finalizedIn)) .next(([finalizedIn, events]) => { const contractEvents: any[] = events @@ -167,48 +137,10 @@ class Contract> { }) } - #call( - origin: Uint8Array, - message: ContractMetadata.Message, - args: Args, - ) { - const { $args } = this.#getMessageCodecByLabel(message.label) - const data = $args.encode([U.hex.decode(message.selector), ...args]) - const callData = U.hex.encode($contractsApiCallArgs.encode([ - origin, - this.contractAddress, - 0n, - undefined, - undefined, - data, - ])) - return C.state - .call(client)("ContractsApi_call", callData) - .next((encodedResponse) => $contractsApiCallResult.decode(U.hex.decode(encodedResponse))) - } - // TODO: codegen each contract message as a method #getMessageByLabel(label: string) { - return this.metadata.V3.spec.messages.find((c) => c.label === label) - } - - #getMessageCodecs(message: C.M.ContractMetadata.Message): MessageCodecs { - return { - $args: C.$.tuple( - // message selector - C.$.sizedUint8Array(U.hex.decode(message.selector).length), - // message args - ...message.args.map((arg) => this.deriveCodec(arg.type.type)), - ), - $result: message.returnType !== null - ? this.deriveCodec(message.returnType.type) - : C.$.constant(null), - } - } - - #getMessageCodecByLabel(label: string) { - return this.$messageByLabel[label]! + return this.contractMetadata.V3.spec.messages.find((c) => c.label === label) } } @@ -216,40 +148,44 @@ const prefix = U.throwIfError(await C.const(client)("System", "SS58Prefix").acce console.log("Deployed Contract address", U.ss58.encode(prefix, contractAddress)) const flipperContract = new Contract(T.polkadot, metadata, contractAddress) -console.log(".get", await flipperContract.query(T.alice.publicKey, "get", []).run()) +console.log(".get", await flipperContract.call(T.alice.address, "get", []).run()) console.log( "block hash and events", - U.throwIfError(await flipperContract.tx(T.alice.publicKey, "flip", [], T.alice.sign).run())[0], + U.throwIfError( + await flipperContract.callTx(T.alice.address, "flip", [], T.alice.sign).run(), + )[0], ) -console.log(".get", await flipperContract.query(T.alice.publicKey, "get", []).run()) -console.log(".get_count", await flipperContract.query(T.alice.publicKey, "get_count", []).run()) +console.log(".get", await flipperContract.call(T.alice.address, "get", []).run()) +console.log(".get_count", await flipperContract.call(T.alice.address, "get_count", []).run()) console.log( ".inc block hash", - U.throwIfError(await flipperContract.tx(T.alice.publicKey, "inc", [], T.alice.sign).run())[0], + U.throwIfError(await flipperContract.callTx(T.alice.address, "inc", [], T.alice.sign).run())[0], ) console.log( ".inc block hash", - U.throwIfError(await flipperContract.tx(T.alice.publicKey, "inc", [], T.alice.sign).run())[0], + U.throwIfError(await flipperContract.callTx(T.alice.address, "inc", [], T.alice.sign).run())[0], ) -console.log(".get_count", await flipperContract.query(T.alice.publicKey, "get_count", []).run()) +console.log(".get_count", await flipperContract.call(T.alice.address, "get_count", []).run()) console.log( ".inc_by(3) block hash", - U.throwIfError(await flipperContract.tx(T.alice.publicKey, "inc_by", [3], T.alice.sign).run())[0], + U.throwIfError( + await flipperContract.callTx(T.alice.address, "inc_by", [3], T.alice.sign).run(), + )[0], ) -console.log(".get_count", await flipperContract.query(T.alice.publicKey, "get_count", []).run()) +console.log(".get_count", await flipperContract.call(T.alice.address, "get_count", []).run()) console.log( ".inc_by_with_event(3) contract events", U.throwIfError( - await flipperContract.tx(T.alice.publicKey, "inc_by_with_event", [3], T.alice.sign).run(), + await flipperContract.callTx(T.alice.address, "inc_by_with_event", [3], T.alice.sign).run(), )[2], ) console.log( ".method_returning_tuple(2,true)", - await flipperContract.query(T.alice.publicKey, "method_returning_tuple", [2, true]).run(), + await flipperContract.call(T.alice.address, "method_returning_tuple", [2, true]).run(), ) console.log( ".method_returning_struct(3,false)", - await flipperContract.query(T.alice.publicKey, "method_returning_struct", [3, false]).run(), + await flipperContract.call(T.alice.address, "method_returning_struct", [3, false]).run(), ) await zombienet.close() From 622a97ab554efba658604bce8c60ef6779075b78 Mon Sep 17 00:00:00 2001 From: Matias Volpe Date: Mon, 19 Dec 2022 15:00:38 -0300 Subject: [PATCH 16/21] feat: add contract event effect --- effects/contracts/call.ts | 29 +++++++++++++---------------- effects/contracts/events.ts | 28 ++++++++++++++++++++++++++++ effects/contracts/mod.ts | 1 + effects/events.ts | 10 ++++++---- examples/smart_contract.ts | 26 ++++---------------------- 5 files changed, 52 insertions(+), 42 deletions(-) create mode 100644 effects/contracts/events.ts diff --git a/effects/contracts/call.ts b/effects/contracts/call.ts index 092af7ac9..05180ed1b 100644 --- a/effects/contracts/call.ts +++ b/effects/contracts/call.ts @@ -29,9 +29,9 @@ export function call>(client: Client_) { args, } = _props as Z.Rec$Access const $message_ = $message(contractMetadata, message) - const data = Z.ls($message_, message, args).next(([{ $args }, message, args]) => { - return $args.encode([U.hex.decode(message.selector), ...args]) - }) + const data = Z.ls($message_, message, args).next(([{ $args }, { selector }, args]) => + $args.encode([U.hex.decode(selector), ...args]) + ) return Z.ls( stateContractsApiCall(client)({ sender, @@ -40,9 +40,7 @@ export function call>(client: Client_) { }), $message_, ) - .next(([result, { $result }]) => { - return $result.decode(result.result.data) - }) + .next(([{ result: { data } }, { $result }]) => $result.decode(data)) } } @@ -66,9 +64,9 @@ export function callTx>(client: Client_) { args, } = _props as Z.Rec$Access const $message_ = $message(contractMetadata, message) - const data = Z.ls($message_, message, args).next(([{ $args }, message, args]) => { - return $args.encode([U.hex.decode(message.selector), ...args]) - }) + const data = Z.ls($message_, message, args).next(([{ $args }, { selector }, args]) => + $args.encode([U.hex.decode(selector), ...args]) + ) const txValue = Z.ls( stateContractsApiCall(client)({ sender, @@ -80,8 +78,8 @@ export function callTx>(client: Client_) { value, data, ) - .next(([{ gasRequired }, contractAddress, value, data]) => { - return { + .next(([{ gasRequired }, contractAddress, value, data]) => ( + { type: "call", dest: MultiAddress.Id(contractAddress), value: value ?? 0n, @@ -89,7 +87,7 @@ export function callTx>(client: Client_) { gasLimit: gasRequired, storageDepositLimit: undefined, } - }) + )) return extrinsic(client)({ sender, call: Z.rec({ type: "Contracts", value: txValue }), @@ -107,16 +105,15 @@ export interface ContractsApiCallProps { export function stateContractsApiCall>(client: Client_) { return >(_props: Props) => { const key = Z.rec(_props as Z.Rec$Access).next( - ({ sender, contractAddress, value, data }) => { - return U.hex.encode($contractsApiCallArgs.encode([ + ({ sender, contractAddress, value, data }) => + U.hex.encode($contractsApiCallArgs.encode([ sender.value!, // TODO: grab public key in cases where we're not accepting multi? contractAddress, value ?? 0n, undefined, undefined, data, - ])) - }, + ])), ) return state .call(client)("ContractsApi_call", key) diff --git a/effects/contracts/events.ts b/effects/contracts/events.ts new file mode 100644 index 000000000..8b39a5833 --- /dev/null +++ b/effects/contracts/events.ts @@ -0,0 +1,28 @@ +import * as $ from "../../deps/scale.ts" +import * as Z from "../../deps/zones.ts" +import { ContractMetadata, DeriveCodec } from "../../frame_metadata/mod.ts" +import { ExtrinsicEvent } from "../events.ts" + +export function events( + contractMetadata: Z.$, + events: Z.$, +) { + const $events = Z.ls(contractMetadata).next(([contractMetadata]) => { + return $.taggedUnion( + "type", + contractMetadata.V3.spec.events + .map((e) => [ + e.label, + [ + "value", + $.tuple(...e.args.map((a) => DeriveCodec(contractMetadata.V3.types)(a.type.type))), + ], + ]), + ) + }) + return Z.ls(events, $events).next(([events, $events]) => { + return events + .filter((e) => e.event?.type === "Contracts" && e.event?.value?.type === "ContractEmitted") + .map((e) => $events.decode(e.event?.value.data)) + }) +} diff --git a/effects/contracts/mod.ts b/effects/contracts/mod.ts index a4a0a9be5..af8dae12e 100644 --- a/effects/contracts/mod.ts +++ b/effects/contracts/mod.ts @@ -1,2 +1,3 @@ export * from "./call.ts" +export * from "./events.ts" export * from "./instantiate.ts" diff --git a/effects/events.ts b/effects/events.ts index 59661b662..a08e44088 100644 --- a/effects/events.ts +++ b/effects/events.ts @@ -24,10 +24,7 @@ export function events - phase: { value: number } - }[]>() + .as() return Z .ls(idx, events) .next(([idx, events]) => { @@ -36,3 +33,8 @@ export function events + phase: { value: number } +} diff --git a/examples/smart_contract.ts b/examples/smart_contract.ts index b8a299d09..bbf6a9293 100644 --- a/examples/smart_contract.ts +++ b/examples/smart_contract.ts @@ -68,23 +68,11 @@ const contractAddress = U.throwIfError( ) class Contract> { - readonly $events - constructor( readonly client: Client, readonly contractMetadata: C.M.ContractMetadata, readonly contractAddress: Uint8Array, - ) { - const deriveCodec = C.M.DeriveCodec(contractMetadata.V3.types) - this.$events = C.$.taggedUnion( - "type", - contractMetadata.V3.spec.events - .map((e) => [ - e.label, - ["value", C.$.tuple(...e.args.map((a) => deriveCodec(a.type.type)))], - ]), - ) - } + ) {} call( sender: C.MultiAddress, @@ -126,15 +114,9 @@ class Contract> { return } ) - return C.Z.ls(finalizedIn, C.events(tx, finalizedIn)) - .next(([finalizedIn, events]) => { - const contractEvents: any[] = events - .filter((e) => - e.event?.type === "Contracts" && e.event?.value?.type === "ContractEmitted" - ) - .map((e) => this.$events.decode(e.event?.value.data)) - return [finalizedIn, events, contractEvents] - }) + const events = C.events(tx, finalizedIn) + const contractEvents = C.contracts.events(this.contractMetadata, events) + return C.Z.ls(finalizedIn, events, contractEvents) } // TODO: codegen each contract message as a method From b6e58828eef6b1d31a3922282ca0f6489122170c Mon Sep 17 00:00:00 2001 From: Matias Volpe Date: Tue, 20 Dec 2022 18:10:54 -0300 Subject: [PATCH 17/21] feat: move contract to fluent --- examples/smart_contract.ts | 148 +++++++++++++++++++------------------ fluent/Contract.ts | 76 +++++++++++++++++++ fluent/mod.ts | 2 + 3 files changed, 154 insertions(+), 72 deletions(-) create mode 100644 fluent/Contract.ts diff --git a/examples/smart_contract.ts b/examples/smart_contract.ts index bbf6a9293..4dc5e1b80 100644 --- a/examples/smart_contract.ts +++ b/examples/smart_contract.ts @@ -67,107 +67,111 @@ const contractAddress = U.throwIfError( .run(), ) -class Contract> { - constructor( - readonly client: Client, - readonly contractMetadata: C.M.ContractMetadata, - readonly contractAddress: Uint8Array, - ) {} - - call( - sender: C.MultiAddress, - messageLabel: string, - args: Args, - ) { - const message = this.#getMessageByLabel(messageLabel)! - return C.contracts.call(client)({ - sender, - contractAddress: this.contractAddress, - contractMetadata: this.contractMetadata, - message, - args, - }) - } - - callTx( - sender: C.MultiAddress, - messageLabel: string, - args: Args, - sign: C.Z.$, - ) { - const message = this.#getMessageByLabel(messageLabel)! - const tx = C.contracts.callTx(client)({ - sender, - contractAddress: this.contractAddress, - contractMetadata: this.contractMetadata, - message, - args, - }) - .signed(sign) - const finalizedIn = tx.watch(({ end }) => - (status) => { - if (typeof status !== "string" && (status.inBlock ?? status.finalized)) { - return end(status.inBlock ?? status.finalized) - } else if (C.rpc.known.TransactionStatus.isTerminal(status)) { - return end(new Error()) - } - return - } - ) - const events = C.events(tx, finalizedIn) - const contractEvents = C.contracts.events(this.contractMetadata, events) - return C.Z.ls(finalizedIn, events, contractEvents) - } - - // TODO: codegen each contract message as a method - - #getMessageByLabel(label: string) { - return this.contractMetadata.V3.spec.messages.find((c) => c.label === label) - } -} - const prefix = U.throwIfError(await C.const(client)("System", "SS58Prefix").access("value").run()) console.log("Deployed Contract address", U.ss58.encode(prefix, contractAddress)) -const flipperContract = new Contract(T.polkadot, metadata, contractAddress) -console.log(".get", await flipperContract.call(T.alice.address, "get", []).run()) +const flipperContract = new C.fluent.Contract(C.polkadot, metadata, contractAddress) +console.log( + ".get", + await flipperContract.call({ + sender: T.alice.address, + messageLabel: "get", + args: [], + }).run(), +) console.log( "block hash and events", U.throwIfError( - await flipperContract.callTx(T.alice.address, "flip", [], T.alice.sign).run(), + await flipperContract.callTx({ + sender: T.alice.address, + args: [], + sign: T.alice.sign, + messageLabel: "flip", + }).run(), )[0], ) -console.log(".get", await flipperContract.call(T.alice.address, "get", []).run()) -console.log(".get_count", await flipperContract.call(T.alice.address, "get_count", []).run()) +console.log( + ".get", + await flipperContract.call({ + sender: T.alice.address, + messageLabel: "get", + args: [], + }).run(), +) +console.log( + ".get_count", + await flipperContract.call({ sender: T.alice.address, messageLabel: "get_count", args: [] }) + .run(), +) console.log( ".inc block hash", - U.throwIfError(await flipperContract.callTx(T.alice.address, "inc", [], T.alice.sign).run())[0], + U.throwIfError( + await flipperContract.callTx({ + sender: T.alice.address, + messageLabel: "inc", + args: [], + sign: T.alice.sign, + }).run(), + )[0], ) console.log( ".inc block hash", - U.throwIfError(await flipperContract.callTx(T.alice.address, "inc", [], T.alice.sign).run())[0], + U.throwIfError( + await flipperContract.callTx({ + sender: T.alice.address, + messageLabel: "inc", + args: [], + sign: T.alice.sign, + }).run(), + )[0], +) +console.log( + ".get_count", + await flipperContract.call({ sender: T.alice.address, messageLabel: "get_count", args: [] }) + .run(), ) -console.log(".get_count", await flipperContract.call(T.alice.address, "get_count", []).run()) console.log( ".inc_by(3) block hash", U.throwIfError( - await flipperContract.callTx(T.alice.address, "inc_by", [3], T.alice.sign).run(), + await flipperContract.callTx({ + sender: T.alice.address, + messageLabel: "inc_by", + args: [3], + sign: T.alice.sign, + }).run(), )[0], ) -console.log(".get_count", await flipperContract.call(T.alice.address, "get_count", []).run()) +console.log( + ".get_count", + await flipperContract.call({ sender: T.alice.address, messageLabel: "get_count", args: [] }) + .run(), +) console.log( ".inc_by_with_event(3) contract events", U.throwIfError( - await flipperContract.callTx(T.alice.address, "inc_by_with_event", [3], T.alice.sign).run(), + await flipperContract.callTx({ + sender: T.alice.address, + messageLabel: "inc_by_with_event", + args: [3], + sign: T.alice.sign, + }).run(), )[2], ) console.log( ".method_returning_tuple(2,true)", - await flipperContract.call(T.alice.address, "method_returning_tuple", [2, true]).run(), + await flipperContract.call({ + sender: T.alice.address, + messageLabel: "method_returning_tuple", + args: [2, true], + }).run(), ) console.log( ".method_returning_struct(3,false)", - await flipperContract.call(T.alice.address, "method_returning_struct", [3, false]).run(), + await flipperContract.call({ + sender: T.alice.address, + messageLabel: "method_returning_struct", + args: [3, false], + }).run(), ) await zombienet.close() diff --git a/fluent/Contract.ts b/fluent/Contract.ts new file mode 100644 index 000000000..5e4d681cd --- /dev/null +++ b/fluent/Contract.ts @@ -0,0 +1,76 @@ +import * as Z from "../deps/zones.ts" +import { contracts, events } from "../effects/mod.ts" +import { ContractMetadata, MultiAddress, Signer } from "../frame_metadata/mod.ts" +import * as rpc from "../rpc/mod.ts" + +export interface ContractCallProps { + sender: MultiAddress + messageLabel: string + args: Args +} +export interface ContractCallTxProps + extends ContractCallProps +{ + value?: bigint + sign: Signer +} + +// TODO: codegen each contract message as a method +// TODO: model ctor inputs as effects +export class Contract> { + constructor( + readonly client: Client, + readonly contractMetadata: ContractMetadata, + readonly contractAddress: Uint8Array, + ) {} + + #basePayload< + Sender extends Z.$, + MessageLabel extends Z.$, + Args extends Z.$, + >( + sender: Sender, + messageLabel: MessageLabel, + args: Args, + ) { + return { + sender, + contractAddress: this.contractAddress, + contractMetadata: this.contractMetadata, + message: this.#getMessageByLabel(messageLabel)!, + args, + } + } + + call>(props: Props) { + return contracts.call(this.client)( + this.#basePayload(props.sender, props.messageLabel, props.args), + ) + } + + callTx>(props: Props) { + const tx = contracts.callTx(this.client)({ + ...this.#basePayload(props.sender, props.messageLabel, props.args), + value: props.value, + }).signed(props.sign) + const finalizedIn = tx.watch(({ end }) => + (status) => { + if (typeof status !== "string" && (status.inBlock ?? status.finalized)) { + return end(status.inBlock ?? status.finalized) + } else if (rpc.known.TransactionStatus.isTerminal(status)) { + return end(new Error()) + } + return + } + ) + const events_ = events(tx, finalizedIn) + const contractEvents = contracts.events(this.contractMetadata, events_) + return Z.ls(finalizedIn, events_, contractEvents) + } + + #getMessageByLabel