When a smart contract has a parameters to be initialized, different instances of the contract will all be at unique addresses. Because of the p2sh standard the specific parameter and template will no longer be visible on-chain. P2sh is really working against developers here to some extent as it’s currently not possible to opt-out of the contract obfuscation it provides.
This creates 3 related issues:
- server requirement: the smart contract application needs to store contract params on a server when there are different unique instances so the contract can be found
- not interoperable: unique instances of p2sh smart contract utxos are not interoperable/findable across different front-ends
- no backups: there’s no standardized way to back-up smart contract params + their script logic, so the contract params/full script can be ‘forgotten’ for p2sh
Using opreturn this can be solved in a nice way as smart contracts can post an identifier for their fixed contract logic and then the values for the unique contract params.
I recently created a project called ‘opreturn scanner’ which can scan the BCH blockchain for these markers. It also includes a list of actively used on-chain markers.
Most markers use 4 bytes fixed encoding (according to the lokad-id spec) but other protocols like Cauldron use custom identifiers. So that is a point of consideration.
Related to opreturn marker discussion @2qx remarked:
The protocol op_return strings of these early dapps (hodl) were influenced by the api available in python.
Sometimes the numeric values are strings. Sometimes data is encoded as text.
In the past, there has been conflict with multiple projects using the same identifier but not coordinating or implementing it correctly.
This adds two interesting points
- anyone can (mis)use your marker for unrelated purposes so this data should always be carefully checked to be in accordance with the protocol/smart contract context
- encoding of data arguments is not always straightforward when there is room for mistakes
additionally, @Jonathan_Silverblood remarked that the 220 bytes limit for opretruns are too small to contain all the anyhedge params, even if they wanted to employ this method as Anyhedge has the following params:
contract AnyHedge_v0_12(
// Mutual redemption
pubkey shortMutualRedeemPublicKey, // 33 B
pubkey longMutualRedeemPublicKey, // 33 B
int enableMutualRedemption, // 1 B
// Arbitrary output lock scripts for Short and Long.
bytes shortLockScript, // 26 B for p2pkh, depends on script type
bytes longLockScript, // 26 B for p2pkh, depends on script type
// Oracle
pubkey oraclePublicKey, // 33 B, verifies message from oracle
// Money
// Note: All int types below must be minimally encoded.
int nominalUnitsXSatsPerBch, // 1~8 B, nominal hedge value in Units, scaled by 1e8(sats/BCH)
int satsForNominalUnitsAtHighLiquidation, // 1~8 B, cost sats for the nominal hedge at high liquidation
int payoutSats, // 1~8 B, total payout sats, miner fee not included
int lowLiquidationPrice, // 1~4 B, clamps price data to ensure valid payouts
int highLiquidationPrice, // 1~4 B, clamps price data to ensure valid payouts
// Time
int startTimestamp, // 4 B, earliest redemption timestamp under liquidation conditions
int maturityTimestamp, // 4 B, required redemption timestamp under maturity conditions
) {
which makes it harder to standardize on this method if it does not work for advanced contracts.
To address this, an increased maximum opreturn size could be considered.