Thread
A thousand eons ago, when I first started learning about blockchain, all videos were using Monopoly or bank accounts as analogies to explain cryptocurrencies. This paints a pretty accurate picture of Ethereum transactions, but Chia works in a completely different way.
To start, there are no accounts in Chia - only coins. Here's how a coin is defined in the official software's source code (chia/types/blockchain_format/coin.py):
class Coin(Streamable):
parent_coin_info: bytes32
puzzle_hash: bytes32
amount: uint64
def name(self) -> bytes32:
return self.get_hash()
[other functions]
parent_coin_info: bytes32
puzzle_hash: bytes32
amount: uint64
def name(self) -> bytes32:
return self.get_hash()
[other functions]
Each coin is defined by 4 important attributes:
* parent_coin_info: the name/id of this coin's parent
* puzzle_hash: the hash of the puzzle of this coin
* amount: the 'value' of the coin, in mojo (1 XCH = 1 trillion mojo)
* parent_coin_info: the name/id of this coin's parent
* puzzle_hash: the hash of the puzzle of this coin
* amount: the 'value' of the coin, in mojo (1 XCH = 1 trillion mojo)
* name: I think of this attribute as a coin id. It is calculated as the hash of the other three values.
As you can see, a coin has no owner. However, it has a puzzle - a program that dictates the coin's behaviour. Like a Phoenix, coins can be destroyed/spent to create new coins.
As you can see, a coin has no owner. However, it has a puzzle - a program that dictates the coin's behaviour. Like a Phoenix, coins can be destroyed/spent to create new coins.
A puzzle dictates how the coin is spent. It accepts a list of arguments (called 'solution') and outputs a list of conditions such as 'create a new coin with this puzzle hash and this amount' or 'this spend is only valid if n blocks have passed since this coin was created'.
It's worth noting that coins have unique names/ids. That means that all coins need to differ by at least one of their three other attributes: parent_coin_info, puzzle_hash, or amount.
So, how does the wallet determine your balance? Well, it's pretty simple. There's a standard puzzle that outputs any conditions as long as the transaction is signed by the private key corresponding to a given public key.
The wallet takes the standard puzzle, curries the public key in (this process is similar to replacing all of the occurences of a variable with a hardcoded value), and calculates the hash of the puzzle. All coins locked by that puzzle hash 'belong to you'.
To be more precise, all coins locked with your puzzle hash can only be destroyed/spent by using your private key. Your address is basically 'your' puzzle hash, except that it's encoded using bech32m - an algorithm that makes it shorter and also allows for error detection.
So no, there are no 'transfers', at least in the traditional sense. However, you can destroy some XCH with 'your' puzzle hash and create new ones with "someone else's" puzzle hash.
What's the deal with offer files? To answer that, we'll need to take a look at SpendBundle (chia/types/spend_bundle.py):
class SpendBundle(Streamable):
coin_spends: List[CoinSpend]
aggregated_signature: G2Element
[code]
class SpendBundle(Streamable):
coin_spends: List[CoinSpend]
aggregated_signature: G2Element
[code]
A CoinSpend contains a coin, a puzzle reveal and a solution. A puzzle reveal is required because coins only contain their respective puzzle hashes. The output conditions are not included; they are generated by each node after running the puzzle with the given solution.
Notice that there was no mention of signatures. Chia uses BLS signatures, which allow aggregation. That means that all signatures can be 'mixed' into one signature that validates the whole SpendBundle, the aggregate_signature.
Offer files are simply incomplete spend bundles. Let's say that I want to buy a Marmot Coin for 10 XCH. I can sign a spend bundle where 10 XCH are destroyed and 1 Marmot Coin is created out of thin air. Of course, this spend bundle will get rejected by the network.
However, I can save it in a file and post it on the internet. People can see my offer by having their wallets parse the .offer file. If John wants to accept my offer, he will create another SpendBundle where 1 Marmot Coin gets destroyed and 10 XCH are created.
By combining the two SpendBundles together and aggregating the signature, John obtains a single SpendBundle in which:
- 10 XCH worth of coins get destroyed
- 10 XCH worth of coins get created
- 1 Marmot Coin gets destroyed
- 1 Marmot Coin gets created
- 10 XCH worth of coins get destroyed
- 10 XCH worth of coins get created
- 1 Marmot Coin gets destroyed
- 1 Marmot Coin gets created
The aggregated signature is also ok, so the resulting SpendBundle is valid. John and I just exchanged 1 Marmot Coin for 10 XCH in a trustless manner. We also interacted with the blockchain only once.
However, what would happen if I wanted to cancel my offer?
However, what would happen if I wanted to cancel my offer?
Well, there's an elegant solution to do just that. Blockchain 101 states that no coin can be spent twice. That means that all I have to do is destroy the coins that I 'used' in the offer file.
I am allowed to create new coins with the same puzzle hashes and amounts since the parent_coin_info field will be different. That means that I can cancel the offer by submitting a transaction that 'sends' the coins involved to myself.
This action will invalidate the SpendBundle that I shared with the world as an offer, thus 'cancelling' the trade. Isn't this awesome?
Okay, Twitter is telling me that I'm approaching a tweet limit (?!?), so I'll wrap this up with a question: would you like to see more of these kind of posts between my sh*tposts? This thread took me about 3 days to think about, so don't expect these kind of things frequently.