Public Storage Contract¶
In the previous tutorial, we deployed and interacted with a HelloWorld contract that emitted an event. Now, we will go a step further and deploy a Storage contract that:
- Stores values on the blockchain
- Retrieves stored values on demand
This tutorial will guide you through deploying, storing, and retrieving data using the Paladin SDK
Prerequisites¶
Before you begin, ensure that you:
- Completed the HelloWorld Tutorial, where you learned:
- How to deploy contracts using the Paladin SDK
- How to send transactions and retrieve receipts
- Have access to a Paladin network to deploy and interact with smart contracts
Overview¶
The Storage
contract provides two primary functions:
store(uint256 num)
– Stores a value in the contractretrieve()
– Retrieves the last stored value
Paladin API & Ethereum Similarities¶
Paladin’s API design follows Ethereum JSON-RPC patterns, making it familiar to developers who have used standard Ethereum APIs:
- Transactions (sendTransaction
) → Similar to eth_sendTransaction
, used for modifying on-chain state
- Calls (call
) → Similar to eth_call
, used for reading blockchain state without modifying it
💡 Numbers in Paladin are passed as strings by default, consistent with JSON-RPC standards
Where to Find the Code?¶
🔹 Example implementation: Paladin example repository
🔹 Solidity contract: Storage.sol
Step 1: Deploy the Contract¶
The first step is to deploy the Storage
contract to the blockchain
const deploymentTxID = await paladin.sendTransaction({
type: TransactionType.PUBLIC,
abi: storageJson.abi,
bytecode: storageJson.bytecode,
from: owner.lookup,
data: {},
});
// Wait for deployment confirmation
const deploymentReceipt = await paladin.pollForReceipt(deploymentTxID, 10000);
if (!deploymentReceipt?.contractAddress) {
logger.error("Deployment failed!");
return false;
}
logger.log(`Step 1: Storage contract deployed successfully at address: ${deploymentReceipt.contractAddress}`);
What Happens Here?¶
- The
sendTransaction
function creates a contract deployment transaction (similar toeth_sendTransaction
) - The
pollForReceipt
function waits for confirmation that the contract has been deployed - If successful, the contract address is returned in the receipt
Step 2: Store a Value¶
Now that the contract is deployed, you can store a value in it using the store
function.
const valueToStore = 125; // Example value to store
logger.log(`Step 2: Storing value "${valueToStore}" in the contract...`);
const storeTxID = await paladin.sendTransaction({
type: TransactionType.PUBLIC,
abi: storageJson.abi,
function: "store",
from: owner.lookup,
to: deploymentReceipt.contractAddress,
data: { num: valueToStore },
});
// Wait for transaction confirmation
const storeReceipt = await paladin.pollForReceipt(storeTxID, 10000);
if (!storeReceipt?.transactionHash) {
logger.error("Failed to store value in the contract!");
return false;
}
logger.log(`Step 2: Value stored successfully in the contract.`);
What Happens Here?¶
- The
sendTransaction
function calls thestore
function with the value125
- The
pollForReceipt
function waits for confirmation that the value has been stored
Step 3: Retrieve the Stored Value¶
Now, retrieve the stored value using the retrieve
function
logger.log("Step 3: Retrieving the stored value...");
const retrieveResult = await paladin.call({
type: TransactionType.PUBLIC,
abi: storageJson.abi,
function: "retrieve",
from: owner.lookup,
to: deploymentReceipt.contractAddress,
data: {},
});
const retrievedValue = retrieveResult["value"];
if (retrievedValue !== valueToStore.toString()) {
logger.error(`Retrieved value "${retrievedValue}" does not match stored value "${valueToStore}"!`);
return false;
}
logger.log(`Step 3: Value retrieved successfully: "${retrievedValue}"`);
What Happens Here?¶
- The
call
function reads the stored value from the contract (similar toeth_call
) - The retrieved value is compared to the original stored value to ensure correctness
💡 Transactions (sendTransaction
) vs. Calls (call
)
- sendTransaction
: Writes data to the blockchain (requires a transaction)
- call
: Reads data from the blockchain (does not modify state)
💡 Why is the number returned as a string? Paladin follows JSON-RPC conventions, where numbers are typically passed as strings to avoid precision loss in JavaScript
Conclusion¶
🎉 Congratulations! You’ve successfully:
- Deployed the
Storage
contract - Stored a value in the contract
- Retrieved the stored value and validated its correctness
You now understand how to deploy and interact with a smart contract using the Paladin SDK, including JSON-RPC number handling and Ethereum transaction conventions
Next Steps¶
Now that you've learned how to deploy a public storage contract, it's time to take things to the next level!
🔒 In the next tutorial, you’ll explore Storage with Privacy, where you will restrict access to stored values using privacy groups