🔗 On chain orders
The validation of orders on Perpetual3 platform is done on-chain with smart contracts
These smart contracts provide a secure environment for confirming and processing customer orders. The central component to this validation process is the use of digital signatures.
The customer supplies orders data signed by the merchant, the smart contract ensures that the submitted data by the customers is indeed authorized by the correct merchant.
The data validation is done by asserting
To implement this, the smart contract includes assertions that check the validity of the digital signature. Here's a simplified version of what's happening on Algorand Blockchain, written in PyTeal:
@ Subroutine(TealType.none)
def customer_new_orderV2():
opup = OpUp(OpUpMode.OnCall)
opup.maximize_budget(Int(10000))
current_round = Global.round()
merchant_pubkey = Txn.application_args[1] # public key of merchant
product_id = Txn.application_args[2] # product id is the hash of the product info
product_id_price = Txn.application_args[3] # price is fiat price+currency
product_id_signature = Txn.application_args[4] # product id signature
merchant_address = Txn.application_args[5] # oracle data
oracle_round = Txn.application_args[6] # oracle round data
oracle_data_signature = Txn.application_args[7] # oracle data signature
oraclePubKey = App.globalGetEx(
Global.current_application_id(), Bytes("oraclePubKey"))
oracle_data_verify = ScratchVar(TealType.bytes)
product_id_data_verify = ScratchVar(TealType.bytes)
payment_type_data_verify = ScratchVar(TealType.bytes)
payment_type_signature = Txn.application_args[8] # payment amount
merchant_address_bytes = Txn.application_args[9]
collection_type = Txn.application_args[10]
collection_name = Txn.application_args[11]
merchant_payment_txn = Gtxn[9]
merchant_paymentType = merchant_payment_txn.type_enum()
pos_payment_txn = Gtxn[14]
Assert(
And(
Btoi(oracle_round) >= Minus(current_round, Int(4)),
Btoi(oracle_round) <= current_round
)
)
return Seq([
oraclePubKey,
Assert(oraclePubKey.hasValue()),
product_id_data_verify.store(
Concat(product_id, product_id_price, collection_type, collection_name)), # collection_type could be null if the product is not connected to a collection
If(merchant_paymentType == TxnType.Payment).Then(
payment_type_data_verify.store(
Concat(Bytes("L1"), merchant_address)),
oracle_data_verify.store(
Concat(
product_id_price,
Bytes("L1"),
Itob(Add(merchant_payment_txn.amount(),
pos_payment_txn.amount())),
oracle_round,
)),
Assert(Ed25519Verify_Bare(payment_type_data_verify.load(),
payment_type_signature, merchant_pubkey)),
Assert(Ed25519Verify_Bare(oracle_data_verify.load(),
oracle_data_signature, oraclePubKey.value())),
Assert(Ed25519Verify_Bare(
product_id_data_verify.load(), product_id_signature, merchant_pubkey)),
If(collection_type == Bytes("phygital")).Then(
phygital_mint(),
verify_payments()
).ElseIf(collection_type == Bytes("tokengate")).Then(
verify_tokengate(),
verify_payments()
).ElseIf(collection_type == Bytes("tokengatephygital")).Then(
phygital_mint(),
verify_tokengate(),
verify_payments()
).ElseIf(collection_type == Bytes("false")).Then(
verify_payments()
)
).ElseIf(merchant_paymentType == TxnType.AssetTransfer).Then(
payment_type_data_verify.store(
Concat(Itob(merchant_payment_txn.xfer_asset()), merchant_address)),
oracle_data_verify.store(
Concat(
product_id_price,
Itob(merchant_payment_txn.xfer_asset()),
Itob(Add(merchant_payment_txn.asset_amount(),
pos_payment_txn.asset_amount())),
oracle_round,
)),
Assert(Ed25519Verify_Bare(payment_type_data_verify.load(),
payment_type_signature, merchant_pubkey)),
Assert(Ed25519Verify_Bare(oracle_data_verify.load(),
oracle_data_signature, oraclePubKey.value())),
Assert(Ed25519Verify_Bare(
product_id_data_verify.load(), product_id_signature, merchant_pubkey)),
If(collection_type == Bytes("phygital")).Then(
phygital_mint(),
verify_payments()
).ElseIf(collection_type == Bytes("tokengate")).Then(
verify_tokengate(),
verify_payments()
).ElseIf(collection_type == Bytes("tokengatephygital")).Then(
phygital_mint(),
verify_tokengate(),
verify_payments()
).ElseIf(collection_type == Bytes("false")).Then(
verify_payments()
)
),
])
Last updated