read.cash is a platform where you can earn money for your articles and comments. You can get paid upvotes
from other users or just earn points for writing articles and comments, which are converted daily to
Bitcoin Cash (BCH) cryptocurrency, which can be used on the Internet or converted to your local money.
All outputs are sent as the regular transaction outputs. (OP_RETURN output is kind of like a "comment" to a transaction. This "comment" would "contain" all the information about SLP tokens in this transaction.)
With the exception of OP_RETURN you need to send some small number of satoshis (546 satoshis = US$0.001 (@$240/BCH) "dust" - the minimal number of satoshis you can send) to the output.
First output is the specially crafted string (starting with OP_RETURN) of type "Genesis":
"Length of the next field" is actually a push operation, which mostly coincides with the length of the next field, see here.
"Mint baton" is a sequential number ("vout", starting with "0" -> OP_RETURN) of the output that allows this output to create or mint additional tokens later. If you omit the baton vout (use 4c00 to omit any field = "zero push") - that means that the initial mint is final and no tokens will be created anymore.
After you broadcast this transaction - you'll get its TX ID. It's now the token_id of this SLP token.
"lokad_id" is the string "SLP" followed by one zero byte.
Now the receiver at vout "1" gets 100000 "base units" of your token (1000.00 tokens).
So, now the receiver of tokens got 1000.00 tokens, let's send them.
If you don't understand why 1000: the receiver got 100'000 "base units". You have selected 2 decimal places during "genesis", so take 100'000, move the decimal point two places to the left and you get: 1'000.00
Another example: Bitcoin Cash has a final circulation of about 21 million BCHs, but it's divisible up to 8 places, so it has a total final circulation of 2'100'000'000'000'000 "base units" named "satoshi" - that's "two quadrillion one hundred trillion satoshis".
Back to sending, you need to build and broadcast this transaction (you can have one or more inputs and up to 19 outputs):
...and the OP_RETURN this time is:
Now, "receiver 1" (vout=1) gets 1E3F (77.43 tokens) and receiver 2 gets DFAC (572.60 tokens). The rest 349.97 tokens are burnt (destroyed) (1000.00-77.43-572.60=349.97).
Again, token_id is the genesis transaction hash.
You always send an integer number of base units. So, if you wanted to send 125.50 US Dollars, you'd actually need to send 12550 US cents.
How do you verify that the user has enough tokens to send? You just go to the parent transactions (look at TXID+vout of each input and verify correctness of their OP_RETURN's (they can be "send", "mint" or "genesis" transactions).. and then you go to their parent inputs.. and theirs... as far as you want to go, best up to the "genesis" transaction).
Miners do not enforce SLP rules for the transactions (but see below about "double spending"). Miners will include incorrect SLP token transactions, which are signed with correct private key of spender, into the blocks, effectively burning tokens according to SLP rules. It's up to the users of SLP tokens to verify the correctness. Thankfully, the protocol is pretty simple to verify.
There's one more type of transaction - that is "commit".
Basically, it's a transaction that states that "at this point in time these SLP transactions for my token were valid, but those weren't valid".
To do that you (as a token creator) commit the hash of your "merklix" tree (don't ask, I don't know) using one more special transaction type and the URL where the users can find the tree.
As far as I understand, this is an optional step that kind of helps SLP token processors.
You'd still need to verify all transactions to ensure that the token issuer is not cheating, so it's better to do something like what SLPDB does, that is to just verify each transaction throughout the history, rather than trusting the issuer with their "commit". It seems certainly easier to trust the commit, but probably software like SLPDB does already build this index too and have the API for getting it and have absolutely no reasons to cheat.
This part of the specification is a bit a mystery to me for the reasons stated in the previous paragraph.
Since, all of the OP_RETURNs that contain information about the token movements are attached to UTXOs (unspent transaction outputs) - miners enforce the regular rules that this UTXO can only be spent by one spending transaction. So, SLP tokens are protected from double spending by the same rules that protect BCH.
Here's a paragraph from the specification:
We emphasize the point, again, that the message has to be perfect in its entirety. For example, if a transaction has 5 outputs, and the fifth output has only 7 bytes instead of 8, then the previous 4 outputs effectively burn the tokens because the entire transaction is invalid.
It wasn't immediately clear to me whether this really "burns" tokens or just marks the transaction as "invalid", meaning that I can use the the parent transaction again to "correctly" spend it, until I wrote the previous paragraph on double spending. If you've spent the UTXO incorrectly (according to SLP, but signed with the valid private key), you're out of luck - miners won't let you spend it again and your tokens are now "burnt" (destroyed).
One more important part is the addresses. By convention you use the simpleledger: prefix in place of bitcoincash: in the addresses where you can send the SLP tokens. This is mostly done to prevent sending tokens using wallets that don't understand SLP.
If you'd try to spend from the UTXO that is linked to the OP_RETURN which has some SLP tokens using simpleledger: address and non-compliant wallet - your transaction just won't go through, even though the letters and numbers after the prefix are the same addresses as in regular BCH.
If you find any errors - please let me know in the comments. Thank you!