Yield Farming in Bitcoin Cash - A practical guide
Yield farming or liquidity mining is the newest trend in crypto, particularly introduced by Ethereum community and with the invention of Compound governance token and is considered the latest trend in DeFi. The basic idea is for participants in a protocol to mine tokens using their liquidity or generally investing on a specific platform.
This concept is new and is not used in many other cryptocurrency communities. I believe many people think performing that kind of functions is not feasible on Bitcoin Cash because the smart contracts on BCH are not as advanced as Ethereum. Even though that notion is true, the very act of minting a SLP token in a decentralized manner is already proven by projects like Mistcoin. https://mistcoin.org/
In this article I like to go in depth into the possibility of Yield Farming in Bitcoin Cash, the implementation and provide you a real sample transaction and Cash Script code that successfully minted a SLP token using an investment (called premium) without any centralized interference.
The Smart Contract
Bitcoin Cash smart contracts are inherently different from platforms like Ethereum. In Ethereum smart contracts are large, they can easily issue tokens and have full access to the state of the protocol. Bitcoin Cash smart contracts are stack based and very limited. However, they are more advanced than Bitcoin in the sense that developers can access the full data of the transaction and **limit the inputs and outputs to specific parameters**. These type of contracts are called **Covenants**. A detailed explanation of the differences between BCH and ETH smart contracts can be found in Rosco Kali's blog post. https://kalis.me/smart-contracts-eth-btc-bch/
SLP Minting Baton
Another element that requires for this type of transactions to work are SLP Minting Batons. Generally anytime someone creates a new SLP token, they can specify a Bitcoin Cash address to store the minting baton. Meaning that everyone who holds control of that address can issue new SLP tokens in the future.
Keeping this Baton in a normal BCH address is very dangerous and a centralized way to keep the supply of a SLP token. The owner of the SLP token have the authority to destroy that Baton to stop the issuance of the new tokens, however in order to do that they have to issue a large amount of tokens and keep them centrally for future use. SLP tokens like Spice or Sour are some of those examples.
Good news that there is a better way to do this as well. A SLP minting Baton can be sent to a smart contract which controls the issuance of the token and takes away any central control over the token. However, the smart contract should be able to provide conditions to prevent minting of the token by actors who did not provide sufficient value for that.
Transaction Details
Considering the elements discussed, we need to perform these actions to create the Yield Farming contract for users of a token:
Create a SLP token with zero issuance
Store the minting baton centrally temporarily to get the genesis TX id (token ID)
Create a smart contract with 2 parameters, **premiumPkh** and **tokenId**
Perform a mint transaction with zero issuance to move the Baton to the P2SH contract forever.
Now every party can spend this contract with an atomic transaction only and only if these conditions are met:
A minimum amount of BCH should be sent to **premiumPkh** ( a normal BCH address or another contract)
Minting baton should be sent back to the **same contract**
Enough BCH should be provided by the farmer to cover the transaction fees and the locked satoshis for the freshly minted tokens
If the transaction by the farmer (end user) is created according to the rules above, the user will end up creating new SLP tokens which will be sent to her address. Failure to do so, will fully reject the transaction and no BCH is lost in the process.
Here is an overview of how this transaction looks like:
You can view the above transaction here. https://explorer.bitcoin.com/bch/tx/708fd137a2abd5b5c20e81bc71ec5fd345c225353c5ef2e24215e2de7626598f
Smart Contract Implementation
Thanks to the efforts done by Rosco Kalis and the sponsors of the Cash Script (General Protocols and Bitcoin.com), this language is evolving to become the standard for BCH smart contracts. The new version of the Cash Script makes the process of working with Covenants pretty straightforward. https://generalprotocols.com/
Here is the code to implement the smart contract described in this example. As you can see, there is no central key in the contract to control the issuance and it makes the contract reusable by everyone for an unlimited amount of time.
This contract is more like a proof of concept and lacks the edge cases like emission control, change addresses or proportional reward according to the premium. So with this contract, a person simply can send a minimum of 1000 satoshi to the premium address to mint 250 new tokens for herself.
contract Yield(bytes20 premiumPkh, bytes tokenIdHex) {
function farm(pubkey farmerPk, sig s, int premium) {
require(checkSig(s, farmerPk));
// minimum amount of premium to be paid in order to farm the yield
int minPremium = 1000;
int satsToBeMinted = 546;
int satsLockedInForBaton = 546;
int dust = 546;
require(premium >= minPremium);
bytes opReturnOut = new OutputNullData([
0x534c5000, // Lokad ID for SLP
0x01,
bytes('MINT'),
tokenIdHex,
0x03, // minting baton vout (very important to avoid burning the baton)
0x00000000000061A8 // 250 SLPs (considering 2 decimals)
]);
// minted token sent back to the farmer
bytes34 out1 = new OutputP2PKH(bytes8(satsToBeMinted), hash160(farmerPk));
// investment to the premium in order to farm
bytes34 out2 = new OutputP2PKH(bytes8(premium), premiumPkh);
// minting baton should be sent back to the contract
bytes32 out3 = new OutputP2SH(bytes8(satsLockedInForBaton), hash160(tx.bytecode));
require(hash256(opReturnOut + out1 + out2 + out3) == tx.hashOutputs);
}
}
Farming the Contract
Farming the contract should happen with inputs from the end-user + the Minting Baton input which is inside the smart contract. This address is reusable by anyone and can be used forever to mint tokens as long as the premium amount is paid (could be investment in another contract or just a one time payment).
Here is an example of how it should look like (in Node JS):
// Making the transaction to pay the premium and mint SLP to alice address using the minting baton
// stored in the smart contract
let tx = await contract.functions
.farm(alicePk, new SignatureTemplate(aliceKeyPair), premiumAmount)
.from(aliceUtxos)
.from(mintingBaton)
.withOpReturn([
"0x534c5000", // Lokad ID
"0x01", // Token type
"MINT", // Action
`0x${tokenId}`, // Token ID
"0x03", // Minting baton vout
"0x00000000000061A8", // mint 250 new tokens (considering 2 decimals)
])
.to(aliceBchAddr, 546) // freshly minted tokens
.to(premiumBchAddr, premiumAmount) // minimum 1000 sats premium is required
.to(contract.address, 546) // minting baton is sent back to contract
.withoutChange()
.send();
The codes demonstrated here are very new and not thoroughly tested or optimized. However the full implementation of this functionality, including the genesis of the token, moving the baton to smart contract and functional mint transaction is maintained in a repository in my Github. Fully open source under the MPL-2.0 license. https://github.com/p0o/yield-farming-bch-smart-contract
Use Cases
There are numerous use cases for this type of contract including but not limited to:
Reward tokens for other contracts (e.g DeFi, AnyHedge, etc)
Governance Token distribution
Decentralized token sales without custody
Loyalty tokens to a merchant's customers
Fundraiser without assurance contract (e.g GoFundMe )
Decentralized Exchange (requires an oracle for rates)
Conclusion
Thanks for following through the article. SLP and Bitcoin Cash smart contracts are amazing technologies and most of the advanced use cases from these technologies are still not utilized. Feel free to get the code, run it and explore the unlimited use cases that you can imagine to build on Bitcoin Cash.
The challenge of using these type of contracts in the wild is the type of transaction that should be constructed differently. There is no native wallet support for these transactions yet, however, if you are familiar with my other project Signup, one of the main plans in the roadmap of that wallet is bringing Bitcoin Cash smart contracts to the web and mainstream apps. Here is the article about Signup's release in case you missed it. https://signup.cash https://read.cash/@SIGNUP/signups-new-bch-web-wallet-is-released-4fcd8576
If you are interested to build a Yield Farming/Reward contract but don't have the required knowledge feel free to reach out to me at my Twitter. I would be happy to help you out. https://twitter.com/p0oker

A sneak peek into SIGNUP's new DApp Architecture for Bitcoin Cash
As introduced in the previous post Signup is a non-custodial platform as service to build DApps for Bitcoin Cash. Our plan is to make it easy for developers to build DApps and make it secure and convenient for users to use these DApps. https://read.cash/@p0oker/announcing-signupcash-empowering-web-based-dapp-ecosystem-in-bitcoin-cash-13935f89
In this article we go through a sneak peek of our new architecture design and look for an early feedback from the community as part of our commitment to a truly community driven open source project. This architecture is still a work in progress.
Challenge
The most challenging part of using DApps across the web and mobile is the problem with having multiple wallets across these web or mobile apps. Moving funds here and there is inconvenient and slow down the adoption for the users and the developers of these apps. Solutions that require users to install a browser extension (MetaMask, Badger etc) partially fix this problem but proved by Ethereum community that they are not a good proposition for mass adoption. In the other hand, web based solutions that empower users to use DApps with one unified account from the comfort of their own browser is booming. Last month Shapeshift acquired Portis which is the web-based decentralized app solution for Ethereuem and MoneyButton raised 1.7M in 2017 for providing similar functionality for BSV community. https://news.yahoo.com/portis-wallet-acquired-shapeshift-120400818.html
Problem With Current Technologies
Even though the current solutions like Portis and MonyButton work in some situations they have problems that we also faced in Signup.cash. The current version of Signup is using some kind of communication between two different threads in the browser to separate the user private keys from the web apps. So a malicious web developer couldn't theoretically steal user's credentials if they intend to do so.
The architecture that is initially developed, uses a sand boxed iframe to communicate with the isolated domain which is **secure.signup.cash.** User's private keys are stored in the local storage of that domain and is secured by browser. Even though this method is working fine, the browser compatibility can never reaches to 100% considering that browser developers are blocking the third party cookies to avoid tracking. This policy is already started by Safari and Brave browser and is possibly gonna spread even further to Chrome mobile.
Also regarding the early version of Signup, many developers were unhappy about the UX of their users because of the explicit confirmation on every transaction. So I considered many other solutions to tackle this problem.
New Architecture
The proposed idea here is a draft and a request for comments to the community. The goal is to empower web and app developers to use the similar techniques they are using in the current industry. Any solution that is different with how things are done in web industry is considered a slow down to the adoption of developers and users.
We already know that app developers are used to common practices like HTTP protocol, JSON Web Tokens and app/session ids. The problem with using these techniques is that all of them are implemented in a custodial way. The whole tech industry is fully custodial, mutable databases sitting in cloud servers and protected by giants like Amazon and Google instead of Cryptography. They never cared about non-custodial solutions, but we do.
Here is a sneak peek of how we propose the communication for a DApp authorization and action flow. This flow contains a Web Worker, a reverse proxy authorization server and a web app. Reverse proxy authorization server is just a relay server that connects the web app with user's non-custodial wallet in a bi-directional SSE connection. That wallet could be a Web Worker in a browser or a Mobile App. https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers https://en.wikipedia.org/wiki/Server-sent_events
This diagram might be overwhelming but it could be simplified into these steps:
Users interact with the Web App for an action (e.g payment transaction)
Web app request for some permission to arbitrarily spend money from user's wallet up to a limit of price and time (maximum $1 in the next 60 minutes)
Wallet generate a self contained token (JWT) for that permission. Token is cryptographically signed and verifiable
Wallet passes the token to the app using the Signup server
The web app now uses the JWT for any kind of transaction up to the limit
The advantage of this architecture is that with minor changes we can use it for authorization using mobile wallets. Signup will also release a mobile app for users who want to keep the custody of their private keys outside their browsers. Other Bitcoin Cash wallets can also integrate the same protocol and enable their users to use DApps using their current wallet!
Here is how the same architecture would work for a mobile app as well:
The only difference in this sequence is that user should:
Open the wallet
Enter a number (sessionId) that they see on their wallet in the web app. (similar to 2FA)
Now they can see the requested permission inside their wallet app and they can confirm or reject it very similar to a hardware wallet.
Now the app can easily perform transactions up to the limits
API is the king
Singup's API is hands down the most simple API out there. All the complexity of the architecture is abstracted into these two lines to authorize and process a transaction:
const user = await signup.cash.authorize({appId: 'YOUR APP ID'});
// requesting your user to pay $1 to you
await user.pay(1, 'USD');
Developers would love it!
Conclusion
The proposed solution is not used in any other similar applications and is a combination of latest best practices in web development and the non-custodial values of crypto community. This solution does not require users to trust any third party with their private keys and do not store user's private keys even in an encrypted way in a centralized server. Also it enables nearly 100% browser compatibility because the technologies used are the same methods and technologies used in most of the web applications in the wild. The user experience is also expected to improve a lot considering the removal of explicit consent screen per transaction.
This document is a draft of the architecture and is out here for feedback and comments. The goal is to develop the most secure and reliable infrastructure for building decentralized apps across the whole crypto community so don't be hesitant to criticize it as ruthlessly as you wish to!
Thanks for reading, don't forget to join our Telegram group for latest updates, visit the website or reach out to me in Twitter to say hi! https://t.me/joinchat/NAXHtw_YK7Qu_MDJt3aOZw https://signup.cash/ https://twitter.com/@p0oker
[sponsors]
Announcing Signup.cash, empowering web based DApp ecosystem in Bitcoin Cash
Link to the article in: Japanese https://www.big-plan.net/signup-cash-announcement/
Web is eating the world, but our community is not getting its fair share. Most web developers in the world do not understand how blockchain works and are not convinced that it might worth the learning curve. But maybe they don't need to learn anything new to use it! That's what Signup is trying to do. In this concise article I will try to go through my motivation for creating Signup, how it works and what goals this project is willing to accomplish.
Problem(s)
Building web apps for Bitcoin cash is not as easy as we wish it to be. Libraries like Bitbox and SLPjs provided access to APIs for broadcasting transactions and utility functions to sign them. They are pretty good, however, three problems are still prevalent.
How to make users trust us with their private key?
How to build BCH transactions? Can't we just ask for specific amount?
How to store data and build social apps? memo protocol is there but everything is closed sourced!
What is Signup?
Signup is a non-custodial platform as a service for developers to build BCH decentralized apps. The core elements of the Signup consist of:
**Key Signing Hub:** A non-custodial wallet on your browser to work like a hardware wallet, requesting for consent from the user and signing transactions.
**Framework:** Utility functions and easy to use API for developers to request users for different type of transactions without exposing the technical side of building a transaction on the blockchain.
**Infrastructure:** Providing all the infrastructure needs of any type of decentralized app for developers so they can focus on building amazing user experience for their users.
How it works for users?
Signup is a universal login like Facebook Login buttons. As a user, in every website you visit you can login to your Signup wallet and be identified using your unique Cash Account. If you are not familiar with Cash Account, it's a specification for a human readable account name that is directly connected to your BCH address (Credit to Jonathan Silverblood).
The web app you logged in can request you for different types of transactions (payment, storing data etc) and you get to choose to accept or deny it. Those web app you log in, would never have access to your private keys and there is no need for a browser extension to be installed.
Upon using any web app that uses Signup technology, the first time you will be asked to create a wallet that comes with a free Cash Account username.
After you're Signed up! You can use any web apps to interact with blockchain. This is how it looks like in a third party web app:
**Try it out** yourself! (**report bugs** if you found them ๐ค) https://examples.p0oker.now.sh/example_login.html https://github.com/signupcash/signup-core/issues
In the example above, the website you clicked the button has no access to your private key or identity, however, it can log you in and recognize you with your unique cash account and BCH address.
For the most basic type of transaction, meaning a tip button it is similar to this:
Try it out yourself! (report bugs if you found them ๐ค) https://examples.p0oker.now.sh/example_simple_tipping_button.html https://github.com/signupcash/signup-core/issues
As you can see developers are totally in control of the experience of the app and are not limited to a set of predefined buttons and components. However, the consent popup in the bottom of the page is always gate-keeping your rights to make sure no transaction happens without your approval.
How it works for developers?
Developers can just use it right away without any registration or API keys. An authentication is as simple as this:
const signup = new SignupCash();
const user = await signup.cash.authenticate();
const { cashAccount, bchAddress } = user.getIdentity();
Requesting your web app's users for a payment would be as simple as this:
const signup = new SignupCash({addr: "DEVELOPER BCH ADDRESS"});
const user = await signup.cash.authenticate();
const { txId } = await user.pay(1000, 'SAT');
After user finished the payment, transaction ID will be returned in the example above.
You can visit our official docs or check out the Github repository for the fully functional example codes above. https://www.notion.so/p0oker/SIGNup-Documentation-88024f39e70041e2a5aa33d2da565ddf https://github.com/signupcash/signup-core
Roadmap
SLP tokens support
Memo Protocol Integration (enabling building social media apps)
Signup key-signer app (keeping the custody of your private key on your phone)
IPFS infrastructure for Signup Storage (TBA)
Anonymized Analytics dashboard for developers
What else you need? Let us know!
What we believe in
Open source everything!
Everyone should be able to join and contribute
Make it damned easy!
Focus on the business use cases rather than fancy tech
Micro payments are the future
Bitcoin is pro business, so we are!
Get involved
Many features are still in progress and there is lots of work to do. Join our Telegram group and say Hi! Want to checkout Signup's code base and learn what we open sourced? Check out the Signup organization page in Github. Also feel free to follow me in Twitter for getting a hang of future updates. https://t.me/joinchat/NAXHtw_YK7Qu_MDJt3aOZw https://github.com/signupcash https://twitter.com/p0oker
Sponsorship or Investment?
Signup is a self funded project, in case you like the idea and are interested to help the project financially, drop me a line at p0oker@pm.me or DM me in Twitter. https://twitter.com/p0oker