Complete guide for using the write functions script to perform state-changing operations on Certifi.
The write-functions.js script provides a complete workflow for:
- Registering institutions
- Managing verifiers
- Issuing credentials
- Verifying credentials
- Revoking credentials
npm run writeThis will execute a complete example workflow:
- Register an institution
- Issue a credential
- Verify the credential
Edit scripts/write-functions.js and uncomment the operations you need.
await registerInstitution(
'University of Lagos',
'Nigeria',
'REG-UNILAG-2024',
'https://metadata.example.com/unilag'
);Parameters:
name(string): Institution namecountry(string): Country nameregNumber(string): Registration numbermetadataUri(string): URI to institution metadata
Returns: Transaction ID
Gas Cost: ~0.01-0.05 STX
await addVerifier('SP2VERIFIER_ADDRESS');Parameters:
verifierAddress(string): Stacks address of verifier
Returns: Transaction ID
Gas Cost: ~0.01-0.05 STX
Note: Only contract owner can add verifiers
await verifyInstitution(0);Parameters:
institutionId(uint): ID of institution to verify
Returns: Transaction ID
Gas Cost: ~0.01-0.05 STX
Note: Only verifiers can verify institutions
const result = await issueCredential(
'SP2STUDENT_ADDRESS',
0,
'Bachelor of Science in Computer Science',
'Student: John Doe, Program: BSc CS, Year: 2024, Grade: A',
'https://metadata.example.com/credential-001'
);
// Returns:
// {
// txid: 'transaction-id',
// hash: 'credential-hash'
// }Parameters:
studentAddress(string): Stacks address of studentinstitutionId(uint): ID of issuing institutioncredentialType(string): Type of credentialcredentialData(string): Credential data (will be hashed)metadataUri(string): URI to credential metadata
Returns: Object with transaction ID and credential hash
Gas Cost: ~0.01-0.05 STX
Note: Credential data is automatically hashed using SHA-256
await verifyCredential(0);Parameters:
credentialId(uint): ID of credential to verify
Returns: Transaction ID
Gas Cost: ~0.01-0.05 STX
await revokeCredential(0, 'Fraudulent credential');Parameters:
credentialId(uint): ID of credential to revokereason(string): Reason for revocation
Returns: Transaction ID
Gas Cost: ~0.01-0.05 STX
const institutionTxId = await registerInstitution(
'University of Lagos',
'Nigeria',
'REG-UNILAG-2024',
'https://metadata.example.com/unilag'
);const verifierTxId = await addVerifier('SP2VERIFIER_ADDRESS');const verifyInstTxId = await verifyInstitution(0);const credentialResult = await issueCredential(
'SP2STUDENT_ADDRESS',
0,
'Bachelor of Science in Computer Science',
'Student: John Doe, Program: BSc CS, Year: 2024, Grade: A',
'https://metadata.example.com/credential-001'
);
console.log('Credential Hash:', credentialResult.hash);const verifyCredTxId = await verifyCredential(0);const revokeTxId = await revokeCredential(0, 'Fraudulent credential');# Edit scripts/write-functions.js
# Comment out all steps except registerInstitution
npm run write# Run default workflow (already includes all steps)
npm run write// Edit scripts/write-functions.js
async function customWorkflow() {
// Your custom operations
const instTxId = await registerInstitution(...);
const credTxId = await issueCredential(...);
const verifyTxId = await verifyCredential(...);
}
customWorkflow();-
Batch Operations
- Combine multiple operations in one script run
- Reduces overhead
-
Test on Testnet First
STACKS_NETWORK=testnet npm run write
-
Monitor Gas Prices
- Check Stacks Explorer before mainnet operations
- Deploy during low-gas periods
-
Use Read-Only Calls First
npm run mainnet-interact
Check data before making state changes
| Operation | Cost |
|---|---|
| Register Institution | 0.01-0.05 STX |
| Add Verifier | 0.01-0.05 STX |
| Verify Institution | 0.01-0.05 STX |
| Issue Credential | 0.01-0.05 STX |
| Verify Credential | 0.01-0.05 STX |
| Revoke Credential | 0.01-0.05 STX |
| Total for all 6 | 0.06-0.30 STX |
-
Test on Testnet
STACKS_NETWORK=testnet npm run write
-
Verify Addresses
- Double-check all Stacks addresses
- Ensure correct institution/credential IDs
-
Review Metadata
- Verify metadata URIs are correct
- Ensure metadata is accessible
-
Use Correct Network
STACKS_NETWORK=mainnet npm run write
-
Monitor Transactions
- Get transaction ID from output
- Visit Stacks Explorer
- Wait for confirmation
-
Keep Records
- Save transaction IDs
- Document credential hashes
- Maintain audit trail
β
INSTITUTION REGISTERED!
Transaction ID: 0x1234567890abcdef...
- Visit: https://explorer.stacks.co/
- Search transaction ID
- Wait for confirmation (10-30 minutes)
Credential Hash: a1b2c3d4e5f6...
Save this for verification later.
async function customOperation() {
try {
console.log(`\nπ CUSTOM OPERATION`);
console.log(`${'β'.repeat(70)}`);
const txOptions = {
contractAddress: INSTITUTIONS_CONTRACT.split('.')[0],
contractName: INSTITUTIONS_CONTRACT.split('.')[1],
functionName: 'your-function',
functionArgs: [
// Your arguments
],
senderKey: DEPLOYER_KEY,
network: NETWORK,
anchorMode: 'onChainOnly',
};
const transaction = await makeContractCall(txOptions);
const broadcastResponse = await broadcastTransaction(transaction, NETWORK);
console.log(`\nβ
OPERATION COMPLETE!`);
console.log(`Transaction ID: ${broadcastResponse.txid}`);
return broadcastResponse.txid;
} catch (error) {
console.error(`\nβ Error:`, error.message);
throw error;
}
}module.exports = {
registerInstitution,
addVerifier,
verifyInstitution,
issueCredential,
verifyCredential,
revokeCredential,
customOperation, // Add your function
};- Check your STX balance
- Add more STX to your account
- Verify you have correct permissions
- Check if you're the contract owner/verifier
- Wait 30+ minutes
- Check network status
- Try again with higher gas
- Verify contract addresses in
deployments/deployment.json - Ensure you're on correct network
async function registerMultiple() {
const institutions = [
{
name: 'University of Lagos',
country: 'Nigeria',
regNumber: 'REG-UNILAG-2024',
uri: 'https://metadata.example.com/unilag'
},
{
name: 'University of Ibadan',
country: 'Nigeria',
regNumber: 'REG-UI-2024',
uri: 'https://metadata.example.com/ui'
}
];
for (const inst of institutions) {
await registerInstitution(
inst.name,
inst.country,
inst.regNumber,
inst.uri
);
}
}async function issueMultiple() {
const credentials = [
{
student: 'SP2STUDENT1',
type: 'Bachelor of Science',
data: 'Student 1 data'
},
{
student: 'SP2STUDENT2',
type: 'Master of Science',
data: 'Student 2 data'
}
];
for (const cred of credentials) {
await issueCredential(
cred.student,
0,
cred.type,
cred.data,
'https://metadata.example.com/credential'
);
}
}β Automatic contract address loading β SHA-256 credential hashing β Transaction monitoring β Error handling β Network detection β Detailed logging β Exportable functions β Easy customization
- MAINNET_INTERACTION.md - Read-only operations
- DEPLOYMENT.md - Deployment guide
- ARCHITECTURE.md - System architecture
-
Test on Testnet
STACKS_NETWORK=testnet npm run write
-
Review Transactions
- Check Stacks Explorer
- Verify operations succeeded
-
Deploy to Mainnet
STACKS_NETWORK=mainnet npm run write
-
Monitor and Maintain
- Keep transaction records
- Monitor contract health
The write functions script provides a complete, gas-optimized way to perform state-changing operations on Certifi. Use it to:
- Register institutions
- Manage verifiers
- Issue credentials
- Verify credentials
- Revoke credentials
Always test on testnet first, monitor gas prices, and keep detailed records of all transactions!