1(module2 (import "seal0" "seal_input" (func $seal_input (param i32 i32)))3 (import "seal0" "seal_get_storage" (func $seal_get_storage (param i32 i32 i32) (result i32)))4 (import "seal0" "seal_set_storage" (func $seal_set_storage (param i32 i32 i32)))5 (import "seal0" "seal_call" (func $seal_call (param i32 i32 i64 i32 i32 i32 i32 i32 i32) (result i32)))6 (import "seal0" "seal_transfer" (func $seal_transfer (param i32 i32 i32 i32) (result i32)))7 (import "seal0" "seal_instantiate" (func $seal_instantiate8 (param i32 i32 i64 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32) (result i32)9 ))10 (import "env" "memory" (memory 1 1))1112 ;; [0, 8) Endowment to send when creating contract.13 (data (i32.const 0) "\00\00\01")1415 ;; [8, 16) Value to send when calling contract.1617 ;; [16, 48) The key to store the contract address under.1819 ;; [48, 80) Buffer where to store the input to the contract2021 ;; [88, 96) Size of the buffer22 (data (i32.const 88) "\FF")2324 ;; [96, 100) Size of the input buffer25 (data (i32.const 96) "\20")2627 ;; [100, 132) Buffer where to store the address of the instantiated contract2829 ;; [132, 134) Salt30 (data (i32.const 132) "\47\11")313233 (func $assert (param i32)34 (block $ok35 (br_if $ok36 (get_local 0)37 )38 (unreachable)39 )40 )4142 (func (export "deploy")43 ;; Input data is the code hash of the contract to be deployed.44 (call $seal_input (i32.const 48) (i32.const 96))45 (call $assert46 (i32.eq47 (i32.load (i32.const 96))48 (i32.const 32)49 )50 )5152 ;; Deploy the contract with the provided code hash.53 (call $assert54 (i32.eq55 (call $seal_instantiate56 (i32.const 48) ;; Pointer to the code hash.57 (i32.const 32) ;; Length of the code hash.58 (i64.const 0) ;; How much gas to devote for the execution. 0 = all.59 (i32.const 0) ;; Pointer to the buffer with value to transfer60 (i32.const 8) ;; Length of the buffer with value to transfer.61 (i32.const 0) ;; Pointer to input data buffer address62 (i32.const 0) ;; Length of input data buffer63 (i32.const 100) ;; Buffer where to store address of new contract64 (i32.const 88) ;; Pointer to the length of the buffer65 (i32.const 4294967295) ;; u32 max sentinel value: do not copy output66 (i32.const 0) ;; Length is ignored in this case67 (i32.const 132) ;; salt_ptr68 (i32.const 2) ;; salt_len69 )70 (i32.const 0)71 )72 )7374 ;; Check that address has expected length75 (call $assert76 (i32.eq77 (i32.load (i32.const 88))78 (i32.const 32)79 )80 )8182 ;; Store the return address.83 (call $seal_set_storage84 (i32.const 16) ;; Pointer to the key85 (i32.const 100) ;; Pointer to the value86 (i32.const 32) ;; Length of the value87 )88 )8990 (func (export "call")91 ;; Read address of destination contract from storage.92 (call $assert93 (i32.eq94 (call $seal_get_storage95 (i32.const 16) ;; Pointer to the key96 (i32.const 100) ;; Pointer to the value97 (i32.const 88) ;; Pointer to the len of the value98 )99 (i32.const 0)100 )101 )102 (call $assert103 (i32.eq104 (i32.load (i32.const 88))105 (i32.const 32)106 )107 )108109 ;; Calling the destination contract with non-empty input data should fail.110 (call $assert111 (i32.eq112 (call $seal_call113 (i32.const 100) ;; Pointer to destination address114 (i32.const 32) ;; Length of destination address115 (i64.const 0) ;; How much gas to devote for the execution. 0 = all.116 (i32.const 0) ;; Pointer to the buffer with value to transfer117 (i32.const 8) ;; Length of the buffer with value to transfer118 (i32.const 0) ;; Pointer to input data buffer address119 (i32.const 1) ;; Length of input data buffer120 (i32.const 4294967295) ;; u32 max sentinel value: do not copy output121 (i32.const 0) ;; Length is ignored in this case122123 )124 (i32.const 0x1)125 )126 )127128 ;; Call the destination contract regularly, forcing it to self-destruct.129 (call $assert130 (i32.eq131 (call $seal_call132 (i32.const 100) ;; Pointer to destination address133 (i32.const 32) ;; Length of destination address134 (i64.const 0) ;; How much gas to devote for the execution. 0 = all.135 (i32.const 8) ;; Pointer to the buffer with value to transfer136 (i32.const 8) ;; Length of the buffer with value to transfer137 (i32.const 0) ;; Pointer to input data buffer address138 (i32.const 0) ;; Length of input data buffer139 (i32.const 4294967295) ;; u32 max sentinel value: do not copy output140 (i32.const 0) ;; Length is ignored in this case141 )142 (i32.const 0)143 )144 )145146 ;; Calling the destination address with non-empty input data should now work since the147 ;; contract has been removed. Also transfer a balance to the address so we can ensure this148 ;; does not keep the contract alive.149 (call $assert150 (i32.eq151 (call $seal_transfer152 (i32.const 100) ;; Pointer to destination address153 (i32.const 32) ;; Length of destination address154 (i32.const 0) ;; Pointer to the buffer with value to transfer155 (i32.const 8) ;; Length of the buffer with value to transfer156 )157 (i32.const 0)158 )159 )160 )161)