๐ Contract Signing โ
Sign transactions with secret keys for smart contract interactions
Overview โ
When interacting with smart contracts, you need to:
- Build the transaction
- Sign it with appropriate keys
- Submit to the network
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ SIGNING FLOW โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ โ
โ โโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโโ โ
โ โ Unsigned โโโโโถโ Prover โโโโโถโ Signed โ โ
โ โ Tx โ โ + Secret โ โ Tx โ โ
โ โโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโโ โ
โ โ โ
โ Secret Key โ
โ or Wallet โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโSigning Methods โ
1. With EIP-12 Wallet (Nautilus, etc.) โ
typescript
// Connect to wallet
await ergoConnector.nautilus.connect();
// Build unsigned transaction
const unsignedTx = new TransactionBuilder(height)
.from(inputs)
.to(output)
.sendChangeTo(address)
.payFee()
.build();
// Sign with wallet
const signedTx = await ergo.signTx(unsignedTx);
// Submit
const txId = await ergo.submitTx(signedTx);
console.log("Transaction ID:", txId);2. With Secret Key (Backend) โ
typescript
import { SecretKey, Prover } from "@fleet-sdk/wallet";
import { TransactionBuilder, OutputBuilder } from "@fleet-sdk/core";
// Your secret key (NEVER expose in frontend!)
const secretKeyHex = "your_secret_key_hex";
const secretKey = SecretKey.fromHex(secretKeyHex);
// Create prover
const prover = new Prover(secretKey);
// Build transaction
const unsignedTx = new TransactionBuilder(currentHeight)
.from(inputs)
.to(new OutputBuilder("1000000000", recipient))
.sendChangeTo(myAddress)
.payFee("1100000")
.build();
// Sign
const signedTx = prover.sign(unsignedTx);
// Submit to node
const response = await fetch("http://node:9053/transactions", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(signedTx)
});Contract Spending โ
When spending from a contract, you may need to satisfy script conditions:
typescript
// Contract that requires specific context
const contractBox = await fetchContractBox();
// Build spending transaction
const tx = new TransactionBuilder(height)
.from([contractBox]) // Contract box as input
.to(
new OutputBuilder(outputValue, recipient)
)
.sendChangeTo(changeAddress)
.payFee()
.build();
// Sign - prover must satisfy contract conditions
const signedTx = prover.sign(tx);Multi-Signature โ
For contracts requiring multiple signatures:
typescript
import { SecretKey, Prover, MultiProver } from "@fleet-sdk/wallet";
// Multiple secret keys
const key1 = SecretKey.fromHex(secretKey1Hex);
const key2 = SecretKey.fromHex(secretKey2Hex);
// Create multi-prover
const prover = new MultiProver([key1, key2]);
// Sign requires all keys
const signedTx = prover.sign(unsignedTx);Hints for Complex Scripts โ
Some scripts need hints to guide signing:
typescript
const signedTx = prover.sign(unsignedTx, {
// Provide hints for script evaluation
hints: {
secretHints: [...],
publicHints: [...]
}
});Security Best Practices โ
| Do | Don't |
|---|---|
| โ Keep secrets server-side | โ Expose keys in frontend |
| โ Use wallet for user txs | โ Store keys in localStorage |
| โ Validate before signing | โ Sign arbitrary data |
| โ Use hardware wallets | โ Share secret keys |
ErgoPay for Mobile โ
For mobile wallet signing, see Reduced Tx & ErgoPay.
Example: Complete Flow โ
typescript
import {
TransactionBuilder,
OutputBuilder,
ErgoAddress
} from "@fleet-sdk/core";
import { SecretKey, Prover } from "@fleet-sdk/wallet";
async function sendErg(
secretKeyHex: string,
recipient: string,
amount: string
) {
// 1. Setup
const secretKey = SecretKey.fromHex(secretKeyHex);
const prover = new Prover(secretKey);
const myAddress = secretKey.getAddress().toString();
// 2. Fetch inputs from blockchain
const inputs = await fetchUtxos(myAddress);
const currentHeight = await getCurrentHeight();
// 3. Build transaction
const unsignedTx = new TransactionBuilder(currentHeight)
.from(inputs)
.to(new OutputBuilder(amount, recipient))
.sendChangeTo(myAddress)
.payFee("1100000")
.build();
// 4. Sign
const signedTx = prover.sign(unsignedTx);
// 5. Submit
const txId = await submitTx(signedTx);
return txId;
}Next Steps โ
- Smart Contracts - Contract interaction tutorial
- ErgoPay Integration - Mobile signing
- Data Inputs - Reference external data