In the following post I will go in-depth over the technical implementation details of our Smart Wedding Contract 🤵👰. Please keep in mind this is a prototype and therefore not intended to be a full featured product (yet).
If you are interested in the overall idea and concept you can read more about it here.
The general idea was to build a digital version of a plain old written marriage contract which handles all required functionalities like managing funds and assets. However, we want to make its digital equivalent not just equivalent but superior, therefore the contract handles dynamic management of funds and assets (which sounds pretty fancy but it’s straight forward 🙂).
Now let’s get our hands on some code.
The first thing to do is to add the spouses wallet addresses as constructor arguments to the contract. These addresses must never be changed again, so that’s the best way to do it.
Uploading the Written Contract
You might ask why would we upload a written contract when the ultimate goal was to create a superior digital version of it. 🤔
The reason is we want it to also work in a legal context. And right now, it wouldn’t work if there is no connection to a plain old written legal document, at least in Austria.
Storing data on Ethereum costs a lot. Based on their Yellow Paper storing a 256 bit word costs 20k gas. Let’s assume the PDF has 100 kB:
100 kB / 256 bit = ~390 (256-bit words)
390 (256-bit words) * 20k (gas) * 10 Gwei (gas price) = 0.078 ETH
Imagine paying $10+ for storing a small file. 😱 If you want to upload a bigger file this could easily cost hundreds if not thousands of dollars. Instead of storing the whole file on Ethereum, we only store the hash of the file on the blockchain and the file it self somewhere else (in this case IPFS).
Signing the Contract
After successfully deploying the contract and uploading the IPFS hash, the Smart Wedding Contract is in an unsigned state.
Both spouses must first sign it with their private keys in order to invoke further functionalities. This is due to the isSigned modifier which checks the state of the contract before invocation.
The signContract function can only be called by a spouse. The “magic” part is the multisig at the end. The if-clause checks if both the husband and the wife have signed the contract. If yes, the global signed state changes to true.
Assets, like e.g. a car, house or even stocks, are the main things managed by a marriage contract which should clarify the following questions:
- Who owns what?
- What happens after divorce?
In opposite to plain old written contracts, where basically every change must be confirmed by a notary, smart contracts enable dynamic asset management.
Adding an Asset
In order to add an asset, one spouse needs to propose it, the other one needs to approve it. Using this function a new asset gets created and the spouse, that suggested to add the asset, immediately approves it.
The asset data is client-side encrypted/decrypted via AES using CryptoJS. So only cypher text is stored on the blockchain to ensure privacy.
Approving an Asset
Assets are approved in the same way (using multisig) as the contract is signed. Only if both spouses agree to add an asset, it gets added.
Removing an Asset
Again, both parties must agree to remove an asset.
Contract as a Savings Account
The Smart Wedding Contract can also be used as kind of a savings account. It acts as a normal Ethereum wallet, which means it can receive ETH. And through the pay function both the wife and the husband can spent those ETH by sending it to another address (e.g. paying for food or holidays, buying other assets, …).
This is the default function. The important keyword is payable. It enables the smart contract to receive funds (ETH).
The pay function only takes a destination address and the amount to send.
Maybe the most important functionality and the reason why a marriage contract exists is what happens after divorce.
The divorce function can only be invoked by spouses. Same as before, they must both agree to divorce. As soon as both parties agree, the contract changes its state to divorced. The remaining funds (ETH) are split by half and sent to each party.
After changing the contracts state to divorced, no one can interact with the contract any more. This is due to the isNotDivorced modifier. It is added to all critical functions to ensure nothing can be changed later on.
The dApp makes use of many events. They are emitted almost at every situation to create a proper log of what happened for the frontend application.
Every event also has a timestamp variable. It is only used to display an approx. time when the event was executed in the web frontend. Web3 also supports this, so it wouldn’t be necessary to log a timestamp with each event, but:
- Web3 needs to asynchronously query a remote Ethereum node for each event (which seems pretty dumb)
- it is free 😍 (storing data in Solidity events costs nothing)
The Smart Wedding Contract is deployed on both the Ropsten testnet and Ethereum mainnet:
Feel free to play with the application 🎮 (make sure to install MetaMask select the Ropsten Testnet). The AES key to decrypt the assets is: block42
The full source code is available at:
A smart marriage contract on Ethereum. Contribute to block42-blockchain-company/smart-wedding-contract development by…
What could be additional features?
A feature could be to add children wallets to the contract, so pocket money could literally be “streamed” into their wallets.
Why are assets implemented as text (strings) and not ERC-20 or ERC-721 tokens?
The main reason is to keep it as simple as possible — it’s a prototype! But it’s definitely a great idea. It would enable the contract to sell the assets by itself and distribute the proceeds to both parties.