I am trying to implement the Soroban example Deployer contract and it fails.
Step 1: deploy basic test contract as shown in example code in the CLI, it works
Step 2: deploy custom contract with extra args in the CLI: it works
Step 3: deploy custom contract in Node using SDK and scVals: it breaks
So I guess it has to do with the native to scVal type conversion, as the CLI takes all strings and it does the conversion itself, and it works
#Soroban example Deployer contract fails on deploy
33 messages · Page 1 of 1 (latest)
Here is the error:
HostError: Error(WasmVm, InvalidAction)
Event log (newest first):
0: [Diagnostic Event] contract:CAKN7QXAWAUTTK5BOLL7WQGJHSDPX66RDREBRUSHIYCZYS27YFPCD43O, topics:[error, Error(WasmVm, InvalidAction)], data:["VM call trapped: UnreachableCodeReached", deploy]
1: [Diagnostic Event] topics:[fn_call, Bytes(14dfc2e0b02939aba172d7fb40c93c86fbfbd11c4818d24746059c4b5fc15e21), deploy], data:[
GDDMYQEROCEBL75ZHJYLSEQMRTVT6BSXQHPEBITCXXQ5GGW65ETQAU5C,
Bytes(64343434383764343233353561633937386464623136633238616334363732643931373731653931386261623037653263633463373638653766366663656536),
Bytes(38363635313634313739),
initialize,
[
GDDMYQEROCEBL75ZHJYLSEQMRTVT6BSXQHPEBITCXXQ5GGW65ETQAU5C,
1,
GCFED2OC5W2S46UYVUY6K3CDFXTCIY2FHU3RN2FM4P2WT224OYTTJXUL,
GAXSRTCK6PFIQHNULHBEJOI4VV2T7YS7SZCXBP6CGGYRI56LCWWMZO7I,
200000000,
CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQVU2HHGCYSC
]
]
Backtrace (newest first):
0: soroban_env_host::vm::Vm::invoke_function_raw
1: soroban_env_host::host::frame::<impl soroban_env_host::host::Host>::with_frame
2: soroban_env_host::host::frame::<impl soroban_env_host::host::Host>::call_n_internal
3: soroban_env_host::host::frame::<impl soroban_env_host::host::Host>::invoke_function_and_return_val::{{closure}}
4: soroban_env_host::host::frame::<impl soroban_env_host::host::Host>::invoke_function
5: soroban_env_host::e2e_invoke::invoke_host_function_in_recording_mode
6: soroban_simulation::simulation::simulate_invoke_host_function_op
7: preflight::preflight_invoke_hf_op::{{closure}}
8: core::ops::function::FnOnce::call_once{{vtable.shim}}
9: preflight::catch_preflight_panic
10: _cgo_0dc58184ddbd_Cfunc_preflight_invoke_hf_op
at tmp/go-build/cgo-gcc-prolog:105:11
11: runtime.asmcgocall
at ./runtime/asm_amd64.s:918
Deployer signature:
env: Env,
deployer: Address,
wasm_hash: BytesN<32>,
salt: BytesN<32>,
init_fn: Symbol,
init_args: Vec<Val>,
) -> (Address, Val) {
Args passed as address, bytes, bytes, symbol, vector
Custom contract constructor:
Vector with args passed as [address, u128, address, address, i128, address]
Should it be a map instead of array?
Call in Node using SDK:
const opr = ctr.call('deploy', ...args)
And it fails in the simulation with the error above
Finally, here are the args converted to scvals:
const orgwallet = 'GDDMYQEROCEBL75ZHJYLSEQMRTVT6BSXQHPEBITCXXQ5GGW65ETQAU5C'
const deployer = new Address(orgwallet).toScVal()
const wasm_hash = nativeToScVal(Buffer.from('d44487d42355ac978ddb16c28ac4672d91771e918bab07e2cc4c768e7f6fcee6'), {type: 'bytes'})
const salt = nativeToScVal(Buffer.from(randomNumber(10)), {type: 'bytes'})
const init_fn = nativeToScVal('initialize', {type: 'symbol'})
const owner = 'GDDMYQEROCEBL75ZHJYLSEQMRTVT6BSXQHPEBITCXXQ5GGW65ETQAU5C'
const admin = new Address(owner).toScVal()
const initiative = nativeToScVal(1, {type: 'u128'})
const provider = new Address('GCFED2OC5W2S46UYVUY6K3CDFXTCIY2FHU3RN2FM4P2WT224OYTTJXUL').toScVal()
const vendor = new Address('GAXSRTCK6PFIQHNULHBEJOI4VV2T7YS7SZCXBP6CGGYRI56LCWWMZO7I').toScVal()
const bucket = nativeToScVal(20*10000000, { type: 'i128' })
const xlm = new Address('CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQVU2HHGCYSC').toScVal()
const init_args = nativeToScVal([admin, initiative, provider, vendor, bucket, xlm], {type: 'vector'})
const args = [deployer, wasm_hash, salt, init_fn, init_args]
Values hardcoded for simplicity
Should I convert args to vector too?
What does VM call trapped: UnreachableCodeReached mean?
Is that in the deployer or the custom contract?
What does VM call trapped: UnreachableCodeReached
that means that your Wasm has panic'd for whatever reason (e.g. an explicitpanic!, or a runtime error like division by zero). one frequent reason for that is passing arguments in bad format (the panic happens at the SDK level)
Bytes(64343434383764343233353561633937386464623136633238616334363732643931373731653931386261623037653263633463373638653766366663656536),
Bytes(38363635313634313739),
it seems your salt is not 32 bytes
hello?
it seems your salt is not 32 bytes
Will fix that and try again
Ok, fixed the salt to 32 bytes but still doesn't work
Now the question is, why the wasm_hash is 64 bytes? Or am I converting it wrong?
Bytes(3234393731323637333332363833313632313733363635363939303132393237),
According to the deployer signature it has to be 32 bytes too, same as the salt
wasm_hash: BytesN<32>,
salt: BytesN<32>,
This is the wasm_hash d44487d42355ac978ddb16c28ac4672d91771e918bab07e2cc4c768e7f6fcee6 according to the CLI when installing the contract
And this the JS assignment
const wasm_hash = nativeToScVal(Buffer.from('d44487d42355ac978ddb16c28ac4672d91771e918bab07e2cc4c768e7f6fcee6'), {type: 'bytes'})
Now the question is, why the wasm_hash is 64 bytes?
yes, it should be 32 bytes
so IDK why is it 64 b in your input
I'm not that familiar with JS SDK, so not sure what does buffer.from expect as the format
Buffer.from is to convert a string to uint8array as bytes
Now d44487d42355ac978ddb16c28ac4672d91771e918bab07e2cc4c768e7f6fcee6 is the wasm_hash result from the CLI after isntalling the contract
How can we convert this hash d44487d42355ac978ddb16c28ac4672d91771e918bab07e2cc4c768e7f6fcee6 to 32 bytes?
That hash is in hex, so it is 64 characters, 64 bytes, and those 64 bytes in hex should map to 32 bytes binary.
There are some examples here that show how to convert a hex string into a Uint8Array depending on if you're in the browser or node: https://stackoverflow.com/questions/38987784/how-to-convert-a-hexadecimal-string-to-uint8array-and-back-in-javascript