Closed readygo67 closed 8 months ago
Hi @readygo67
Thank you for raising this issue. Let me explain several reasons why this contract unfortunately won't work on the contracts
pallet (the target runtime for solang compile --target polkadot
).
Those instructions are very low level. They can't be fully supported in Solang because of the intrinsic differences between the underlying contract runtimes (EVM and pallet-contracts
that is).
Even though Wasm has a linear memory, which is somewhat comparable with the linear memory in EVM, which would allow to use mnemonics like mstore
and mload
. It would break most existing contracts. Wasm contracts on pallet-contracts
use that memory differently, datastructures exhibit different memory layouts and the data encoding is different too. This makes certain mnemonics, like the ones in your contract, incompatible with runtimes other than the EVM.
For example, looking at the first line of code in the plonk verifier you posted:
let mem := mload(0x40)
In the EVM, the "free memory pointer" is found in the linear memory at offset 0x40
. This isn't the case on pallet-contracts
and would break that code even if Solang would support mstore
.
calldataload
faces another problem: Contracts compiled for Solangs polkadot
target use SCALE
encoding, which is quite different to what they use for Solidity on EVM. Thus, even if Solang would support it, this would break nearly all existing contracts, because they assume EVM ABI encoding while on the contracts-pallet
the call data will be SCALE
encoded. For Solidity source code, the compiler can internally handle this, making it fully opaque, which is however not possible for assembly instructions like these.
Note that this code calls into precompiles not avaiable in a vanilla pallet-contracts
runtime, for example to perform bn128
curve operations. The contracts
pallet does not provide precompiles neither does it provide the functioniality of those precompiles out of the box. Instead, there are chain extensions that can be used by any polkadot parachain to implement such functionalities.
As an example of how this could look like, you can check out our tornado cash integration test.
It would also be thinkable to implement a whole plonk verifier directly in a chain extension, making it faster and the contract way simpler.
Contracts that heavily rely on intrinsic EVM functionality are inherently not portable. Trying to run or port such a contract on a Wasm contract runtime would be somewhat analogous to trying to get an x86
linux bianry to work on an ARM MacOS. Unfortunately, I don't think there is an easy way to re-use this plonk verifier contract without re-writing it first.
@xermicus thanks for your info
in my solidity file, many assembly code used, when I try to compile it to wasm, it shows
hope to know whether solang supports evm assembly code?