Latest news about Bitcoin and all cryptocurrencies. Your daily crypto news habit.
Before reading this tutorial, you should have a basic understanding of how Stellar works and how to create a simple account on the test network. Take a look at my previous article in this series to get you updated.
This article will explain to you how to develop an escrow smart contract using Stellar Lumens. I will as well highlight some extra features like retrieving a balance and a clean history log.
Extra note: This article is part of the Blockchaingers series. Together with TheLedger, we have won the ‘Digital Nations Infrastructure’ track at the largest blockchain hackathon. You can find out more about our idea here. Escrow smart contracts on the Stellar testnet are part of this prototype.
Use Case Description
We have two identities: a house and a contractor. The house can pay a contractor for delivering house related services like a check-up of your central heating. Once the house and contractor agree to deliver a service, the house will deposit the agreed amount (in XLM) into the escrow smart contract. Once the job is done, both the house and contractor have to sign to release the funds.
Preparation
First, we need a new, empty account on the testnet. Let’s create one.
const newKey = Stellar.Keypair.random();
const transaction = new Stellar.TransactionBuilder(ownerAccount) .addOperation(Stellar.Operation.createAccount({ destination: escrowPubKey, startingBalance: '2.5000000' })) .build();
transaction.sign(ownerKeypair);
return StellarConfig.server.submitTransaction(transaction);
We still have to define an owner account who is responsible for creating the escrow but is not able to perform any actions with it. We use a config file for retrieving our server, this piece of code is the same as: new Stellar.Server('https://horizon-testnet.stellar.org'); which creates a new connection with the Stellar testnet.
Probably, you wonder why I’m sending 2.5 XLM to the escrow? Stellar reequires that each account has a starting balance of 1 XLM. In addition, we are adding two more signers besides the random escrow signer. For each signer you add to the contract, you have to top up the starting balance with 0.5 XLM. So, …
3 x 0.5 (signers) + 1 (base balance) = 2.5
Additional info can be found in the Stellar documentation.
Building Stellar Escrow Transaction
Let’s retrieve the escrow account,
const escrowAccount = StellarConfig.server.loadAccount(pubKey);
and build the escrow transaction.
let transaction = new Stellar.TransactionBuilder(escrowAccount) .addOperation(Stellar.Operation.setOptions({ signer: { ed25519PublicKey: houseKeypair.publicKey(), weight: 1 } })) .addOperation(Stellar.Operation.setOptions({ masterWeight: 0, lowThreshold: 2, medThreshold: 2, highThreshold: 2, signer: { ed25519PublicKey: contractorKeypair.publicKey(), weight: 1 } })) .build();
As you can see, we’ve added two signers to the escrow contract. We give both signers equal voting power (1) and set the threshold to two. Because we are not giving the escrow account itself an explicit weight, this is set to zero. This means both the house and contractor have to sign to release the funds, not the escrow owner. You can see an example of an escrow smart contract transaction creation here.
At last, we need to sign (with the random keypair) and send the transaction to the network.
transaction.sign(newKey);await StellarConfig.server.submitTransaction(transaction);
Ideally, the house sends the agreed amount to the escrow smart contract. The code for sending the top up transaction looks like this.
memo = Stellar.Memo.text('Pay: House to Contractor');return new Stellar.TransactionBuilder(<source-account>, { memo }) .addOperation(Stellar.Operation.payment({ <destination-pub-key>, asset: Stellar.Asset.native(), <amount>
})).build();
Release Funds
Releasing the funds is actually very simple. You create a new transfer transaction from the escrow account to the contractor. The only difference here is that both the house and contractor have to sign with their keypair.
transaction.sign(houseKeyPair);transaction.sign(contractorKeyPair);
Additional Operations
Retrieve History For Account
This will give you a list of all payments a certain account has executed. We remove the first result (with shift()) from the array as that’s the account creation transaction (a 0 XLM payment to itself).
async retrievePayments(pubKey:string) { let account = await this.loadAccountAsync(pubKey); let payments = await axios.get(`${StellarConfig.baseUrl}/accounts/${account.accountId()}/payments`);
let paymentRecords = payments.data._embedded.records; paymentRecords.shift();
return paymentRecords.map(record => { return { id: record.transaction_hash, from: record.from, to: record.to, amount: record.amount }; });}
You can use the HTTP API endpoint /accounts/<account-ID>/payments to retrieve this in your web browser as well. You’ll get something like:
One payment object (history) for an account.Get Account Balance
To retrieve the XLM balance of an account, you just have to load (retrieve) the account based on its public key. As an account can have multiple balances (native XLM and other coins deployed on the Stellar network), we will only look for the native balance.
async getBalance(pubKey) { const account = await StellarConfig.server.loadAccount(pubKey); let balance;
account.balances.forEach((balanceObject) => { if (balanceObject.asset_type === 'native') { balance = balanceObject.balance; } });
return balance;}
Source: https://www.in3dc.com
What to read next
- Exploring Stellar Lumens | Introduction Development Tutorial
- Builders of the Decentralized Web: 10 Of The Most Innovative Technologies
- The tech-stack to win the worlds biggest blockchain hackathon of 2018!
Stellar Escrow Smart Contract Development was originally published in Hacker Noon on Medium, where people are continuing the conversation by highlighting and responding to this story.
Disclaimer
The views and opinions expressed in this article are solely those of the authors and do not reflect the views of Bitcoin Insider. Every investment and trading move involves risk - this is especially true for cryptocurrencies given their volatility. We strongly advise our readers to conduct their own research when making a decision.