Project
compiler
Describe the feature
Overview
Currently, there is no way for the outside observer to deduce a simplicityhl smart contract interface. The entrypoint (spend) functions are hidden under the witness fields, which makes source code parsing and witness generation extremely tedious. This issue proposes a way to standardise the spending interface.
Impact
Having a clean smart contract interface would enable, first and foremost, two things:
-
Non-leaky autogenerated witness construction for calling specific entrypoints. We are already doing this generation in simplex, but it's far from being ideal due to witness parsing complexity.
-
Clean presentation of the "spend" inside a wallet (Blockstream App). Users will be able to see which function of the smart contract is being called.
High-level feature request
Before
Here is a dummy simplicityhl contract that showcases the complexity of understanding the spending interface:
fn deposit(data: u256) {
// ...
}
fn withdraw(sig: Signature) {
// ...
}
fn claim(sigs: [Signature; 2]) {
// ...
}
fn main() {
match witness::PATH {
Left(deposit_data: u256) => deposit(deposit_data),
Right(withdraw_or_claim: Either<Signature, [Signature; 2]>) => match withdraw_or_claim {
Left(withdraw_sig: Signature) => withdraw(withdraw_sig),
Right(claim_sigs: [Signature; 2]) => claim(claim_sigs),
},
}
}
After
The proposed change:
entry fn deposit(data: u256) {
// ...
}
entry fn withdraw(sig: Signature) {
// ...
}
entry fn claim(sigs: [Signature; 2]) {
// ...
}
One way of doing this
Instead of requiring a user to specify a main function in every contract, the compiler may generate it automatically.
Every entry function will be assigned a special funcid = sha256(<function name + parameter types>)[0:4].
In our example:
- The
funcid for deposit is sha256("deposit(u256)")[0:4] = 0xb15ec5fa.
- The
funcid for withdraw is sha256("withdraw(Signature)")[0:4] = 0x397bbc03.
- The
funcid for claim is sha256("claim([Signature;2])")[0:4] = 0x6c29f44d.
Then, to spend a contract via an entrypoint function, a contract will expect a witness variable PATH to exist and start with a funcid. The compiler will build a "virtual binary tree" inside the main function in a deterministic (and known) manner that parses the PATH variable and deduces which function the user is intending to call.
The compiler may output a special JSON file specifying such entrypoints. The offchain tools may then provide functionality to build the witness for users only by accepting this JSON, a function name, and its parameters.
Hope this request is not a super long shot. I'd love to hear your opinion regarding this.
Project
compiler
Describe the feature
Overview
Currently, there is no way for the outside observer to deduce a simplicityhl smart contract interface. The entrypoint (spend) functions are hidden under the witness fields, which makes source code parsing and witness generation extremely tedious. This issue proposes a way to standardise the spending interface.
Impact
Having a clean smart contract interface would enable, first and foremost, two things:
Non-leaky autogenerated witness construction for calling specific entrypoints. We are already doing this generation in simplex, but it's far from being ideal due to witness parsing complexity.
Clean presentation of the "spend" inside a wallet (Blockstream App). Users will be able to see which function of the smart contract is being called.
High-level feature request
Before
Here is a dummy simplicityhl contract that showcases the complexity of understanding the spending interface:
After
The proposed change:
One way of doing this
Instead of requiring a user to specify a
mainfunction in every contract, the compiler may generate it automatically.Every
entryfunction will be assigned a specialfuncid = sha256(<function name + parameter types>)[0:4].In our example:
funcidfordepositissha256("deposit(u256)")[0:4]=0xb15ec5fa.funcidforwithdrawissha256("withdraw(Signature)")[0:4]=0x397bbc03.funcidforclaimissha256("claim([Signature;2])")[0:4]=0x6c29f44d.Then, to spend a contract via an entrypoint function, a contract will expect a witness variable
PATHto exist and start with afuncid. The compiler will build a "virtual binary tree" inside the main function in a deterministic (and known) manner that parses thePATHvariable and deduces which function the user is intending to call.The compiler may output a special JSON file specifying such entrypoints. The offchain tools may then provide functionality to build the witness for users only by accepting this JSON, a function name, and its parameters.
Hope this request is not a super long shot. I'd love to hear your opinion regarding this.