Proof of Care is a verified-outcome payment system. The core mechanic:
TZ-TON-2026-00421)Current state (MVP): Google Sheets + WhatsApp video proofs + fiat payments
Target state: Smart contracts + crypto wallets for actors + NFT donor receipts + on-chain proof anchoring + dashboard
Here’s why Base is the right choice for Proof of Care specifically:
Cost — Gas fees are ~$0.001–$0.01 per transaction. At 1,000 children × ~10 on-chain events each, your total chain cost is under $100. Ethereum mainnet would be $5–$50 per transaction.
Stablecoin — USDC is native on Base (Coinbase is a USDC issuer). All actor payments and donor contributions stay in USD value. No volatility risk for a CSO saving for land.
Mobile wallets — Coinbase Smart Wallet lets a nurse in rural Tanzania create a wallet with just a phone number or email — no seed phrase, no technical knowledge. This is critical for your mobile-first actors.
Offramp — Coinbase has the best Africa offramp infrastructure (Yellow Card, Kotani Pay integrations) to convert USDC → mobile money (M-Pesa, MTN MoMo).
NFTs — ERC-721 is the gold standard. Donor NFTs will be compatible with every major wallet and marketplace.
Now I can see exactly how the system works. This is brilliant — the © symbol is a hash connector, and each column builds a growing chain of proof. Let me map it precisely before writing the contracts:
Col A: 11156TAN-ACH-F03-255078908780-© ← Child (ID + country + diagnosis + age/sex + phone hash)
Col B: ©-145LET-mhzNY2QZsh0-© ← Outreach (worker ID + YouTube video hash)
Column C- develops an AI marketing donor ask report
Col D: ©-234MAL-75-341-322=© ← Donor (donor ID + $ splits: outreach/surgery/aftercare)
Col E: A+B+D (×3 rows = Outreach/Hospital/Aftercare authorised)
Col G: ©-1234SEL-ELI-ACH-mhzNY2QZsh0-© ← Surgery (hospital + surgeon + procedure + video)
Col H: A+B+D+G ← Full chain through surgery
Col I: ©-221ZIL-NUR-22-mhzNY2QZsh0-© ← Aftercare (location + nurse + days + video)
Col J: Full chain including aftercare ← HOME CONFIRMED = outcome complete
Column K – Verification
Col L: POC Admin — rate, pay, star rating
ProofOfCareOutcome.sol — The heart. Every column in your spreadsheet maps to a function:
registerChild() → Col A (creates the first © hash)submitOutreachProof() → Col B (extends hash + issues pending tokens)authoriseDonor() → Col D/E (USDC into escrow, NFT minted, splits locked forever)submitSurgeryProof() → Col GsubmitAftercareProof() → Col IsubmitHomeProof() → Col J (full chain complete)verifyOutcome() → Col K (star rating + sign-off)releasePayout() → Col L (all actors paid, all tokens unlock simultaneously)The © concatenation becomes an on-chain keccak256 hash that grows identically to your spreadsheet chain.
ProofOfCareCoin.sol — Tokens stay PENDING (unspendable) until the full chain is verified. If an outcome fails or fraud is flagged, they expire to zero — never minted.
ProofOfCareNFT.sol — Donor NFT mints the moment USDC is deposited, then updates automatically at each proof stage. Fully on-chain SVG — no IPFS, no servers to go down. Shows the child ID, journey stage, star rating, and all three video links at completion.
ProofOfCareCoin.sol ERC-20 actor incentive tokens (POC)
ProofOfCareNFT.sol ERC-721 donor journey receipts (POCJ)
ProofOfCareOutcome.sol Core outcome lifecycle + USDC escrow| Spreadsheet Column | Field | Contract Function |
|---|---|---|
| Col A — Child | 11156TAN-ACH-F03-255078908780-© | registerChild() |
| Col B — Outreach | ©-145LET-mhzNY2QZsh0-© | submitOutreachProof() |
| Col C — POC-Donor Story | AI generated (off-chain) | stored as metadata |
| Col D — Donor | ©-234MAL-75-341-322=© | authoriseDonor() |
| Col E — Donor Authorising | Full chain A+B+D | chainHash computed |
| Col G — WHO Surgery | ©-1234SEL-ELI-ACH-mhzNY2QZsh0-© | submitSurgeryProof() |
| Col H — Full chain+surgery | A+B+D+G | chainHash updated |
| Col I — Aftercare Nursing | ©-221ZIL-NUR-22-mhzNY2QZsh0-© | submitAftercareProof() |
| Col J — Home confirmed | Full chain | submitHomeProof() |
| Col K — Verifier | None / Sign-off | verifyOutcome() |
| Col L — POC Admin Pay | Rate and Pay ★★★★★ | releasePayout() |
In the spreadsheet, the © symbol concatenates each actor’s data into a growing proof string. On-chain, this becomes:
outcomeId = keccak256(childId + country + diagnosis + demographics + phone + timestamp)
after outreach: = keccak256(outcomeId + workerCode + videoId)
after donor: = keccak256(prev + donorId + splits)
after surgery: = keccak256(prev + hospitalCode + surgeonCode + procedure + videoId)
after aftercare: = keccak256(prev + location + nurseCode + days + videoId)
after home: = keccak256(prev + "HOME" + videoId)The final chainHash stored on-chain is the tamper-proof receipt of the entire journey. Anyone can verify it by replaying the events.
REGISTERED → Child ID assigned, actors setOUTREACH_PROVEN → BEFORE video submitted, outreach hash added
DONOR_AUTHORISED → USDC escrowed, NFT minted, splits locked
SURGERY_PROVEN → DURING video submitted, surgery hash added
AFTERCARE_PROVEN → Recovery logged, aftercare hash added
HOME_CONFIRMED → Child home, full © chain complete
VERIFIED → Independent verifier sign-off
PAID → All actors paid, tokens unlocked
FAILED → Tokens expired, USDC returned to donorStage Actor Tokens (default) Status
──────────────────────────────────────────────────────────────
Outreach outreachWorker 200 POC
Surgery surgeon 1500 POC
Hospital hospital 600 POC
Aftercare aftercareNurse 300 POC
Verifier verifier 200 POC
5-star bonus surgeon 150 POC
──────────────────────────────────────────────────────────────
2750 POC
→ All UNLOCK together when releasePayout() is called
→ All EXPIRE (worth zero) if flagOutcomeFailed() is called
→ Actors redeem POC tokens → POC sends USDC to named beneficiary
(land seller, school, etc.) — NOT to actor directlyoutreachBps: 1500 → $90 (15%) outreachWorker
surgeryBps: 5000 → $150 (25%) surgeon
$150 (25%) hospital
aftercareBps: 1500 → $90 (15%) aftercareNurse
localAdminBps: 2000 → $120 (20%) hospital (admin)
─────────────────────────────────────────────────────
TOTAL: 10000 → $600 (100%)# Install dependencies
npm install --save-dev hardhat @nomicfoundation/hardhat-toolbox
npm install @openzeppelin/contracts
# Deploy to Base Mainnet
npx hardhat run scripts/deploy.js --network baseconst { ethers } = require("hardhat");
async function main() {
const [deployer] = await ethers.getSigners();
const POC_ADMIN = deployer.address;
// Base USDC address
const USDC_BASE = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913";
console.log("Deploying Proof of Care contracts...");
console.log("Admin:", POC_ADMIN);
// 1. Deploy POC Coin
const Coin = await ethers.getContractFactory("ProofOfCareCoin");
const coin = await Coin.deploy(POC_ADMIN);
await coin.waitForDeployment();
console.log("ProofOfCareCoin:", await coin.getAddress());
// 2. Deploy POC NFT
const NFT = await ethers.getContractFactory("ProofOfCareNFT");
const nft = await NFT.deploy(POC_ADMIN);
await nft.waitForDeployment();
console.log("ProofOfCareNFT:", await nft.getAddress());
// 3. Deploy Outcome (main contract)
const Outcome = await ethers.getContractFactory("ProofOfCareOutcome");
const outcome = await Outcome.deploy(
POC_ADMIN,
await coin.getAddress(),
await nft.getAddress(),
USDC_BASE
);
await outcome.waitForDeployment();
console.log("ProofOfCareOutcome:", await outcome.getAddress());
// 4. Grant roles — outcome contract can mint/burn coins and update NFTs
const MINTER_ROLE = ethers.keccak256(ethers.toUtf8Bytes("MINTER_ROLE"));
const BURNER_ROLE = ethers.keccak256(ethers.toUtf8Bytes("BURNER_ROLE"));
const UPDATER_ROLE = ethers.keccak256(ethers.toUtf8Bytes("UPDATER_ROLE"));
await coin.grantRole(MINTER_ROLE, await outcome.getAddress());
await coin.grantRole(BURNER_ROLE, await outcome.getAddress());
await nft.grantRole(MINTER_ROLE, await outcome.getAddress());
await nft.grantRole(UPDATER_ROLE, await outcome.getAddress());
console.log("\n✓ All contracts deployed and roles configured");
console.log("\nNext: Update .env with contract addresses and run verification");
}
main().catch(console.error);require("@nomicfoundation/hardhat-toolbox");
require("dotenv").config();
module.exports = {
solidity: {
version: "0.8.20",
settings: { optimizer: { enabled: true, runs: 200 } }
},
networks: {
base: {
url: "https://mainnet.base.org",
accounts: [process.env.DEPLOYER_PRIVATE_KEY],
chainId: 8453
},
"base-sepolia": { // ← test here first
url: "https://sepolia.base.org",
accounts: [process.env.DEPLOYER_PRIVATE_KEY],
chainId: 84532
}
},
etherscan: {
apiKey: { base: process.env.BASESCAN_API_KEY }
}
};Recommended: Coinbase Smart Wallet
Alternative: Valora (Celo-based, Africa-focused)
1. Donor visits POC dashboard
2. Selects child outcome to fund (or POC assigns one)
3. Donor approves USDC spend → calls authoriseDonor()
4. NFT (POCJ token) minted to donor wallet immediately
5. NFT updates automatically as child progresses through stages
6. On completion: NFT shows ★★★★★ + all 3 video links1. Actor accumulates POC tokens over multiple outcomes
2. Actor wants to buy land / pay school fees
3. Actor calls redeem(amount) on ProofOfCareCoin
4. POC admin receives notification
5. POC admin sends USDC directly to land seller / school
(NOT to actor — mirrors whitepaper "redemption to vendor" design)
6. Transaction logged on-chain| Fraud Attempt | Why It Fails |
|---|---|
| Fake child | Must have chain hash from Col A — no number, no work |
| Fake video | YouTube ID is hashed into the chain — can’t swap |
| Skip a stage | Contract enforces strict stage order |
| Double count | outcomeId is unique — second registration reverts |
| Early payment | USDC locked until Stage.VERIFIED — no exceptions |
| Ghost worker | Tokens tied to registered wallet addresses only |
| Corrupt verifier | POC admin role separate from VERIFIER role |
Base Sepoliahttps://sepolia.base.org84532ETHhttps://sepolia.basescan.orgGo to https://faucet.quicknode.com/base/sepolia — paste your MetaMask wallet address and request ETH. You’ll get ~0.1 ETH which is more than enough for all your test transactions (each costs fractions of a cent).
.sol files@openzeppelin/contracts from GitHub on its own.ProofOfCareCoin.sol → ProofOfCareNFT.sol → ProofOfCareOutcome.solDeploy contract 1 — ProofOfCareCoin:
ProofOfCareCoin in the contract dropdownDeploy contract 2 — ProofOfCareNFT:
ProofOfCareNFTDeploy contract 3 — ProofOfCareOutcome:
ProofOfCareOutcome_pocAdmin: your wallet address_pocCoin: the ProofOfCareCoin address you copied_pocNFT: the ProofOfCareNFT address you copied_usdc: for testnet use a mock — paste 0x036CbD53842c5426634e7929541eC2318f3dCF7e (that’s real USDC on Base Sepolia)This wires the contracts together. In the deployed contracts panel at the bottom, expand ProofOfCareCoin and find grantRole.
You need to run 4 transactions total:
On ProofOfCareCoin — call grantRole twice:
0x9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6 (MINTER_ROLE), Account: [ProofOfCareOutcome address]0x3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a848 (BURNER_ROLE), Account: [ProofOfCareOutcome address]On ProofOfCareNFT — call grantRole twice:
0x7c8999dc9a822c1f0df42023113094f984f032613c31c99a24f70d7d1c5c08d7 (UPDATER_ROLE) + Outcome addressTip: In Remix you can compute role hashes by pasting e.g.
keccak256("MINTER_ROLE")into the search — or just copy the hashes above.
Now call functions on ProofOfCareOutcome in order. Use these test values:
registerChild(
"11156TAN-ACH-F03-255078908780", // childId
"TAN", // country
"ACH", // diagnosisCode
"F03", // demographics
"255078908780", // phoneRemixed
[1500, 5000, 1500, 2000], // allocation (must sum to 10000)
0xYOUR_ADDRESS, // outreachWorker (use your own for testing)
0xYOUR_ADDRESS, // surgeon
0xYOUR_ADDRESS, // hospital
0xYOUR_ADDRESS, // aftercareNurse
0xYOUR_ADDRESS // verifier
)After each call, copy the outcomeId from the transaction logs in the Remix console — you’ll pass it into every subsequent function. Then call each step in order. After releasePayout you can check the NFT was minted and the POC tokens were unlocked.
The whole thing runs in about 20 minutes and costs nothing. Once that works cleanly, you’re ready to deploy to Base Mainnet with real USDC.
Every person in the system is motivated by the same finish line — Amina safely home.
In the old charity model, the outreach worker gets paid for finding a child. The surgeon gets paid for doing surgery. Nobody gets paid for the outcome. So nobody’s incentive is actually the outcome.
In POC, the outcome is the only thing that releases money. That’s not a philosophy — it’s a contract that enforces it automatically.
The © chain in the spreadsheet, and the keccak256 hash in the smart contract, are both doing the same thing: building an unforgeable record that proves each person did their part, in order, for this specific child. That’s what makes it auditable to a government, trustworthy to a donor, and fair to a field worker in rural Tanzania who has never had reliable income before.