Add storage set example for Substrate.

This commit is contained in:
Jacques Wagener 2020-01-14 17:43:24 +02:00
parent 1a82f47a4e
commit f5059e5826
No known key found for this signature in database
GPG Key ID: C294D1025DA0E923
6 changed files with 69 additions and 17 deletions

View File

@ -94,8 +94,8 @@ SUBSTRATE_POSTPROCESS=tools/substrate_postprocess.sh
substrate-examples: substrate-examples:
$(WASM32_NIMC) --out:examples/substrate/hello_world.wasm examples/substrate/hello_world.nim $(WASM32_NIMC) --out:examples/substrate/hello_world.wasm examples/substrate/hello_world.nim
$(SUBSTRATE_POSTPROCESS) examples/substrate/hello_world.wasm $(SUBSTRATE_POSTPROCESS) examples/substrate/hello_world.wasm
$(WASM32_NIMC) --out:examples/substrate/flipper.wasm examples/substrate/flipper.nim $(WASM32_NIMC) --out:examples/substrate/setter.wasm examples/substrate/setter.nim
$(SUBSTRATE_POSTPROCESS) examples/substrate/flipper.wasm $(SUBSTRATE_POSTPROCESS) examples/substrate/setter.wasm
.PHONY: test-substrate .PHONY: test-substrate
test-substrate: substrate-examples test-substrate: substrate-examples

View File

@ -0,0 +1,13 @@
extern unsigned char __heap_base;
unsigned int bump_pointer = &__heap_base;
void* malloc(int n) {
unsigned int r = bump_pointer ;
bump_pointer += n;
return (void *)r;
}
void free(void* p) {
// lol
}

View File

@ -5,7 +5,7 @@ proc malloc(n: int): pointer {.importc.}
type type
Action = enum Action = enum
Flip = 0'u8, Get = 1'u8, SelfEvict = 2'u8 Set = 0'u8, Get = 1'u8, SelfEvict = 2'u8
# Init function. # Init function.
proc deploy(): uint32 {.exportwasm.} = proc deploy(): uint32 {.exportwasm.} =
@ -21,6 +21,25 @@ proc get_scratch(): (pointer, int32) =
proc print(s: cstring) = proc print(s: cstring) =
ext_println(s, s.len.int32) ext_println(s, s.len.int32)
proc incr_pointer(oldp: pointer): pointer =
var newp = cast[pointer](cast[uint](oldp) + 1u)
newp
proc set_val_in_store(scratch_ptr: pointer, scratch_size: int32) =
print("Set".cstring)
var
key: array[32, byte] = [
2'u8, 2'u8, 2'u8, 2'u8, 2'u8, 2'u8, 2'u8, 2'u8, 2'u8,
2'u8, 2'u8, 2'u8, 2'u8, 2'u8, 2'u8, 2'u8, 2'u8, 2'u8,
2'u8, 2'u8, 2'u8, 2'u8, 2'u8, 2'u8, 2'u8, 2'u8, 2'u8,
2'u8, 2'u8, 2'u8, 2'u8, 2'u8
]
offset_ptr = incr_pointer(scratch_ptr)
ext_set_storage(addr key, 1.int32 , offset_ptr, scratch_size - 1)
# Main function. # Main function.
proc call(): uint32 {.exportwasm.} = proc call(): uint32 {.exportwasm.} =
var var
@ -30,14 +49,14 @@ proc call(): uint32 {.exportwasm.} =
copyMem(addr selector, scratch_ptr, 1) copyMem(addr selector, scratch_ptr, 1)
case selector case selector
of Action.Flip.ord: of Action.Set.ord:
print("Flip".cstring) set_val_in_store(scratch_ptr, scratch_size)
of Action.Get.ord: of Action.Get.ord:
print("Get".cstring) print("Get: Todo".cstring)
of Action.SelfEvict.ord: of Action.SelfEvict.ord:
print("SelfEvict".cstring) print("SelfEvict: Todo".cstring)
else: else:
print("Unknown".cstring) print("Unknown action passed".cstring)
0 # return 0 # return

View File

@ -14,7 +14,7 @@ proc ext_scratch_read*(dest_ptr: pointer, offset: int32, len: int32)
proc ext_scratch_size*(): int32 proc ext_scratch_size*(): int32
proc ext_scratch_write*(src_ptr: pointer, len: int32) proc ext_scratch_write*(src_ptr: pointer, len: int32)
proc ext_set_rent_allowance*(value_ptr: pointer, value_len: int32) proc ext_set_rent_allowance*(value_ptr: pointer, value_len: int32)
proc ext_set_storage*(key_ptr: pointer, value_non_null: int32, value_ptr: int32, value_len: int32) proc ext_set_storage*(key_ptr: pointer, value_non_null: int32, value_ptr: pointer, value_len: int32)
proc ext_value_transferred*() proc ext_value_transferred*()
{.pop.} {.pop.}

View File

@ -46,9 +46,29 @@ beforeEach(
} }
); );
describe("Nimplay Hellow World", () => {
describe("Nimplay Flipper", () => {
test("Can deploy and execute", async (done): Promise<void> => { test("Can deploy and execute", async (done): Promise<void> => {
const codeHash = await putCode(
api,
testAccount,
"../../../examples/substrate/hello_world.wasm"
);
expect(codeHash).toBeDefined();
const address: Address = await instantiate(
api,
testAccount,
codeHash,
"0x00",
CREATION_FEE
);
expect(address).toBeDefined();
await callContract(api, testAccount, address, "0x00");
done();
});
});
describe("Nimplay Storage Setter", () => {
test("Setter: Can deploy and execute", async (done): Promise<void> => {
// See https://github.com/paritytech/srml-contracts-waterfall/issues/6 for info about // See https://github.com/paritytech/srml-contracts-waterfall/issues/6 for info about
// how to get the STORAGE_KEY of an instantiated contract // how to get the STORAGE_KEY of an instantiated contract
@ -57,12 +77,11 @@ describe("Nimplay Flipper", () => {
const codeHash = await putCode( const codeHash = await putCode(
api, api,
testAccount, testAccount,
"../../../examples/substrate/flipper.wasm" "../../../examples/substrate/setter.wasm"
); );
expect(codeHash).toBeDefined(); expect(codeHash).toBeDefined();
// Instantiate a new contract instance and retrieve the contracts address // Instantiate a new contract instance and retrieve the contracts address
// Call contract with Action: 0x00 = Action::Flip()
const address: Address = await instantiate( const address: Address = await instantiate(
api, api,
testAccount, testAccount,
@ -81,10 +100,12 @@ describe("Nimplay Flipper", () => {
expect(initialValue.toString()).toEqual(""); expect(initialValue.toString()).toEqual("");
await callContract(api, testAccount, address, "0x00"); await callContract(api, testAccount, address, "0x00");
await callContract(api, testAccount, address, "0x01"); var val_hex = "03".repeat(32);
await callContract(api, testAccount, address, "0x74657374"); // "0x00" indicates calling "Set" Action
await callContract(api, testAccount, address, "0x00" + val_hex);
const newValue = await getContractStorage(api, address, STORAGE_KEY);
expect(newValue.toString()).toEqual("0x" + val_hex);
done(); done();
}); });
}); });

View File

@ -45,7 +45,6 @@ export async function putCode(
console.error("ERROR: No code stored after executing putCode()"); console.error("ERROR: No code stored after executing putCode()");
} }
// Return code hash. // Return code hash.
console.log(record);
return record.event.data[0]; return record.event.data[0];
} }