Skip to content

Commit

Permalink
Escrow example and finish e2e example (#33)
Browse files Browse the repository at this point in the history
Co-authored-by: i <[email protected]>
  • Loading branch information
qwadratic and i authored Apr 2, 2024
1 parent 6786ee8 commit be57714
Show file tree
Hide file tree
Showing 2 changed files with 217 additions and 6 deletions.
31 changes: 25 additions & 6 deletions examples/e2e.eg.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ const devnet = Mina.LocalBlockchain({
})
Mina.setActiveInstance(devnet)

const fee = 1e8

const [deployer, owner, alexa, billy] = devnet.testAccounts as TestAccounts
const contract = PrivateKey.randomKeypair()

Expand All @@ -17,7 +19,7 @@ const token = new FungibleToken(contract.publicKey)
console.log("Deploying token contract.")
const deployTx = await Mina.transaction({
sender: deployer.publicKey,
fee: 1e8,
fee,
}, () => {
AccountUpdate.fundNewAccount(deployer.publicKey, 1)
token.deploy({
Expand All @@ -30,7 +32,7 @@ const deployTx = await Mina.transaction({
await deployTx.prove()
deployTx.sign([deployer.privateKey, contract.privateKey])
const deployTxResult = await deployTx.send().then((v) => v.wait())
console.log("Deploy tx result:", deployTxResult)
console.log("Deploy tx result:", deployTxResult.toPretty())
equal(deployTxResult.status, "included")

const alexaBalanceBeforeMint = token.getBalanceOf(alexa.publicKey).toBigInt()
Expand All @@ -40,15 +42,15 @@ equal(alexaBalanceBeforeMint, 0n)
console.log("Minting new tokens to Alexa.")
const mintTx = await Mina.transaction({
sender: owner.publicKey,
fee: 1e9,
fee,
}, () => {
AccountUpdate.fundNewAccount(owner.publicKey, 1)
token.mint(alexa.publicKey, new UInt64(2e9))
})
await mintTx.prove()
mintTx.sign([owner.privateKey])
const mintTxResult = await mintTx.send().then((v) => v.wait())
console.log("Mint tx result:", mintTxResult)
console.log("Mint tx result:", mintTxResult.toPretty())
equal(mintTxResult.status, "included")

const alexaBalanceAfterMint = token.getBalanceOf(alexa.publicKey).toBigInt()
Expand All @@ -62,15 +64,15 @@ equal(alexaBalanceBeforeMint, 0n)
console.log("Transferring tokens from Alexa to Billy")
const transferTx = await Mina.transaction({
sender: alexa.publicKey,
fee: 1e9,
fee,
}, () => {
AccountUpdate.fundNewAccount(billy.publicKey, 1)
token.transfer(alexa.publicKey, billy.publicKey, new UInt64(1e9))
})
await transferTx.prove()
transferTx.sign([alexa.privateKey, billy.privateKey])
const transferTxResult = await transferTx.send().then((v) => v.wait())
console.log("Transfer tx result:", transferTxResult)
console.log("Transfer tx result:", transferTxResult.toPretty())
equal(transferTxResult.status, "included")

const alexaBalanceAfterTransfer = token.getBalanceOf(alexa.publicKey).toBigInt()
Expand All @@ -80,3 +82,20 @@ equal(alexaBalanceAfterTransfer, BigInt(1e9))
const billyBalanceAfterTransfer = token.getBalanceOf(billy.publicKey).toBigInt()
console.log("Billy balance after transfer:", billyBalanceAfterTransfer)
equal(billyBalanceAfterTransfer, BigInt(1e9))

console.log("Burning Billy's tokens")
const burnTx = await Mina.transaction({
sender: billy.publicKey,
fee,
}, () => {
token.burn(billy.publicKey, new UInt64(6e8))
})
await burnTx.prove()
burnTx.sign([billy.privateKey])
const burnTxResult = await burnTx.send().then((v) => v.wait())
console.log("Burn tx result:", burnTxResult.toPretty())
equal(burnTxResult.status, "included")

const billyBalanceAfterBurn = token.getBalanceOf(billy.publicKey).toBigInt()
console.log("Billy balance after burn:", billyBalanceAfterBurn)
equal(billyBalanceAfterBurn, BigInt(4e8))
192 changes: 192 additions & 0 deletions examples/escrow.eg.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
import { equal } from "node:assert"
import {
AccountUpdate,
DeployArgs,
method,
Mina,
PrivateKey,
PublicKey,
SmartContract,
State,
state,
UInt64,
} from "o1js"
import { TestAccounts } from "test_util.js"
import { FungibleToken } from "../index.js"

export class TokenEscrow extends SmartContract {
@state(PublicKey)
tokenAddress = State<PublicKey>()
@state(UInt64)
total = State<UInt64>()

deploy(args: DeployArgs & { tokenAddress: PublicKey }) {
super.deploy(args)

this.tokenAddress.set(args.tokenAddress)
this.total.set(UInt64.zero)
}

@method
deposit(from: PublicKey, amount: UInt64) {
const token = new FungibleToken(this.tokenAddress.getAndRequireEquals())
token.transfer(from, this.address, amount)
const total = this.total.getAndRequireEquals()
this.total.set(total.add(amount))
}

@method
withdraw(to: PublicKey, amount: UInt64) {
const token = new FungibleToken(this.tokenAddress.getAndRequireEquals())
const total = this.total.getAndRequireEquals()
total.greaterThanOrEqual(amount)
this.total.set(total.sub(amount))
token.transfer(this.address, to, amount)
}
}

const devnet = Mina.LocalBlockchain({
proofsEnabled: false,
enforceTransactionLimits: false,
})
Mina.setActiveInstance(devnet)

const fee = 1e8

const [deployer, owner, alexa, billy, jackie] = devnet.testAccounts as TestAccounts
const tokenContract = PrivateKey.randomKeypair()
const escrowContract = PrivateKey.randomKeypair()
console.log(`
deployer ${deployer.publicKey.toBase58()}
owner ${owner.publicKey.toBase58()}
alexa ${alexa.publicKey.toBase58()}
billy ${billy.publicKey.toBase58()}
jackie ${jackie.publicKey.toBase58()}
token ${tokenContract.publicKey}
escrow ${escrowContract.publicKey}
`)
const token = new FungibleToken(tokenContract.publicKey)
const escrow = new TokenEscrow(escrowContract.publicKey)

console.log("Deploying token contract.")
const deployTokenTx = await Mina.transaction({
sender: deployer.publicKey,
fee,
}, () => {
AccountUpdate.fundNewAccount(deployer.publicKey, 1)
token.deploy({
owner: owner.publicKey,
supply: UInt64.from(10_000_000_000_000),
symbol: "abc",
src: "https://github.com/MinaFoundation/mina-fungible-token/blob/main/examples/escrow.eg.ts",
})
})
await deployTokenTx.prove()
deployTokenTx.sign([deployer.privateKey, tokenContract.privateKey])
const deployTokenTxResult = await deployTokenTx.send().then((v) => v.wait())
console.log("Deploy tx result:", deployTokenTxResult.toPretty())
equal(deployTokenTxResult.status, "included")

console.log("Deploying escrow contract.")
const deployEscrowTx = await Mina.transaction({
sender: deployer.publicKey,
fee,
}, () => {
AccountUpdate.fundNewAccount(deployer.publicKey, 1)
escrow.deploy({
tokenAddress: tokenContract.publicKey,
})
})
await deployEscrowTx.prove()
deployEscrowTx.sign([deployer.privateKey, escrowContract.privateKey])
const deployEscrowTxResult = await deployEscrowTx.send().then((v) => v.wait())
console.log("Deploy tx result:", deployEscrowTxResult.toPretty())
equal(deployEscrowTxResult.status, "included")

console.log("Minting new tokens to Alexa and Billy.")
const mintTx1 = await Mina.transaction({
sender: owner.publicKey,
fee,
}, () => {
AccountUpdate.fundNewAccount(owner.publicKey, 1)
token.mint(alexa.publicKey, new UInt64(2e9))
})
await mintTx1.prove()
mintTx1.sign([owner.privateKey])
const mintTxResult1 = await mintTx1.send().then((v) => v.wait())
console.log("Mint tx result 1:", mintTxResult1.toPretty())
equal(mintTxResult1.status, "included")

const mintTx2 = await Mina.transaction({
sender: owner.publicKey,
fee,
}, () => {
AccountUpdate.fundNewAccount(owner.publicKey, 1)
token.mint(billy.publicKey, new UInt64(3e9))
})
await mintTx2.prove()
mintTx2.sign([owner.privateKey])
const mintTxResult2 = await mintTx2.send().then((v) => v.wait())
console.log("Mint tx result 2:", mintTxResult2.toPretty())
equal(mintTxResult2.status, "included")

console.log("Alexa deposits tokens to the escrow.")
const depositTx1 = await Mina.transaction({
sender: alexa.publicKey,
fee,
}, () => {
AccountUpdate.fundNewAccount(alexa.publicKey, 1)
escrow.deposit(alexa.publicKey, new UInt64(2e9))
})
await depositTx1.prove()
depositTx1.sign([alexa.privateKey])
const depositTxResult1 = await depositTx1.send().then((v) => v.wait())
console.log("Deposit tx result 1:", depositTxResult1.toPretty())
equal(depositTxResult1.status, "included")

const escrowBalanceAfterDeposit1 = token.getBalanceOf(escrowContract.publicKey).toBigInt()
console.log("Escrow balance after deposit:", escrowBalanceAfterDeposit1)
equal(escrowBalanceAfterDeposit1, BigInt(2e9))

console.log("Billy deposits tokens to the escrow.")
const depositTx2 = await Mina.transaction({
sender: billy.publicKey,
fee,
}, () => {
// note that there is no need to fund escrow token account as its already exists
escrow.deposit(billy.publicKey, new UInt64(3e9))
})
await depositTx2.prove()
depositTx2.sign([billy.privateKey])
const depositTxResult2 = await depositTx2.send().then((v) => v.wait())
console.log("Deposit tx result 2:", depositTxResult2.toPretty())
equal(depositTxResult2.status, "included")

const escrowBalanceAfterDeposit2 = token.getBalanceOf(escrowContract.publicKey).toBigInt()
console.log("Escrow balance after deposit:", escrowBalanceAfterDeposit2)
equal(escrowBalanceAfterDeposit2, BigInt(5e9))

const escrowTotalAfterDeposits = await escrow.total.get()
equal(escrowTotalAfterDeposits.toBigInt(), escrowBalanceAfterDeposit2)

console.log("Escrow deployer withdraws portion of tokens to Jackie.")
const withdrawTx = await Mina.transaction({
sender: deployer.publicKey,
fee,
}, () => {
AccountUpdate.fundNewAccount(deployer.publicKey, 1)
escrow.withdraw(jackie.publicKey, new UInt64(4e9))
})
await withdrawTx.prove()
withdrawTx.sign([deployer.privateKey, escrowContract.privateKey])
const withdrawTxResult = await withdrawTx.send().then((v) => v.wait())
console.log("Withdraw tx result:", withdrawTxResult.toPretty())
equal(withdrawTxResult.status, "included")

const escrowBalanceAfterWithdraw = token.getBalanceOf(escrowContract.publicKey).toBigInt()
console.log("Escrow balance after deposit:", escrowBalanceAfterDeposit2)
equal(escrowBalanceAfterWithdraw, BigInt(1e9))

const escrowTotalAfterWithdraw = await escrow.total.get()
equal(escrowTotalAfterWithdraw.toBigInt(), escrowBalanceAfterWithdraw)

0 comments on commit be57714

Please sign in to comment.