CashAccount Report: May2021
It has been a year since I followed up on the adoption metrics for the CashAccounts payment aliasing protocol that stores your data on the Bitcoin Cash blockchain. https://read.cash/@JonathanSilverblood/cashaccounts-report-may2020-00a40beb
While there hasn't been any significant recent developments, and users continue to ask on places like twitter and reddit as to why wallet developers haven't adopted the functionality yet, adoption continues to move and shows now signs of slowing down.
Disclaimer: Not all data is good data.
Like last years report, I've decided to exclude the some data that I feel severaly skews the statistics in an unreasonable ways:
bitcoincash: qrdk...3erp (creating one account per block to gather statistics).
bitcoincash:qqrr...xy5p (testing and vast majority of names are ytest).
bitcoincash:qzvm...w4qs (testing and vast majority of names ate testXX).
bitcoincash:qztp...dxe2 (programmatically created and likely test/spam).
bitcoincash:qqrw...2ghc (strong outliers with systematic name luckyXX or forumXX).
bitcoincash:qpeu...d2ds (strong outliers with systematic name pancakeXX).
bitcoincash:qqy9...tgx2 (strong outliers with systematic name ectest).
bitcoincash:qz3x...6x7c (strong outliers with systematic name testse).
baby636 (spammy nature across BCH ecosystem)
BABY636 (spammy nature across BCH ecosystem)
BitcoinCash (variation of Bitcoin)
Bitcoincash (variation of Bitcoin)
bitcoincash (variation of Bitcoin)
Bitcoin (variation of Bitcoin)
bch (variation of Bitcoin)
BCH (variation of Bitcoin)
Test (testing oriented name)
test (testing oriented name)
test2 (testing oriented name)
a (testing oriented name)
CashAccount (variation of CashAccount)
Cashaccount (variation of CashAccount)
cashaccount (variation of CashAccount)
50000 (numerical repetition)
30000 (numerical repetition)
25000 (numerical repetition)
20000 (numerical repetition)
10000 (numerical repetition)
5000 (numerical repetition)
4000 (numerical repetition)
3000 (numerical repetition)
2000 (numerical repetition)
1000 (numerical repetition)
500 (numerical repetition)
100 (numerical repetition)
50 (numerical repetition)
20 (numerical repetition)
10 (numerical repetition)
7 (numerical repetition)
5 (numerical repetition)
1 (numerical repetition)
0 (numerical repetition)
*This list is not exhaustive and I know that there's still a some amount of test/experiment related data include, but I believe we get rid of ~90% of the non-user data this way.*
Current usage and comparison to last year
year accounts unique_names unique_payloads
---------- ---------- ------------ ---------------
2020: 7882 5241 6741
2021: 19418 12574 17435
We now have almost 20,000 accounts with about 17500 unique payloads. There has been some growth (+146%) over the year as the adoption rate continues to increase. As always, we can't know how many actual users there are or how many accounts they have on average.
week after release unique_names unique payloads
------------------ ------------ ---------------
1 1064 1092
The fastest growing week since inception is still the very release week, but on week 90 we hit 970 unique payloads, which is getting close to the same level as the release week.
Looking at the state of the system at the end of the previous report, after the first wallets opted to automatically create cashaccounts for their users, we can see that average new paylods per week is about `220 per week`:
week after release unique_names unique payloads
------------------ ------------ ---------------
61 64 80
62 80 124
63 49 76
64 97 113
65 577 593
66 438 500
67 94 147
68 97 177
69 187 323
70 83 134
71 98 148
Looking at the following `42` weeks, we can see a clear growth and only fell back under 100 per week at two occasions:
week after release unique_names unique payloads
------------------ ------------ ---------------
72 199 254
73 118 162
74 468 496
75 74 107
76 428 483
77 88 143
78 135 186
79 171 216
80 233 290
81 126 172
82 107 161
83 428 504
84 148 221
85 143 218
86 168 237
87 160 217
88 132 171
89 355 397
90 924 970
91 219 234
92 331 362
93 159 187
94 94 124
95 114 155
96 113 146
97 129 152
98 155 260
99 163 214
100 61 110
101 39 72
102 64 105
103 55 95
104 77 138
105 99 178
106 80 141
107 156 284
108 180 340
109 353 679
110 138 229
111 127 205
112 267 508
113 314 606
114 252 488
How has the user experience panned out?
One of the concerns of the CashAccount protocol is that multiple users registering their names at the same time will get longer and longer account identifiers and the value of the system would gradually erode.
Now that we have well over yet another year worth of data, we can take a look to see how common this is, and how strong of an impact it has had.
accounts percent account_collision_count unique_names unique_payloads
-------- ------- ----------------------- ------------ ---------------
653 3.4 2 273 371
116 0.6 3 38 53
48 0.2 4 10 25
45 0.2 5 8 12
6 0.0 6 1 1
10 0.1 10 2 4
1 0.0 17 1 1
With a total of around **4.5%** of registered accounts having had collisions, it now looks better than the **6.5%** measured last year, but that might come down to better filtering of systematic, spammy and testing accounts. Regardless, we should quantify how strongly affected the accounts were by the collision mechanic:
accounts percent account_collision_length unique_names unique_payloads
-------- ------- ------------------------ ------------ ---------------
758 3.9 1 298 406
105 0.5 2 39 64
14 0.1 3 6 10
2 0.0 4 1 1
about **3.9%** of the accounts need to use a single extra number in order to ensure uniqueness and **0.5%** need to use two digits extra. The system appears to be working as predicted, which is consistent with the fact that there still hasn't been any user complaints or user support requests on this matter the last year.
What about the error rate?
At the start of the system, there was some failed registrations on the blockchain where the party trying to register an account has properly indicated that they want to register a CashAccount by using the CashAccount protocol identifier, but have then failed to follow the specification. In the last year, this statistic has not changed as not a single failed registration has been detected since.
Where do we go from here?
With the protocol having been live for years now, I have found that it's convenient to use for the cases where it works out, but that wallet support is still abysmall. Reusable Private Addresses is still being worked on which would allow CashAccounts to function with reasonable privacy.
To get this system used more, what is needed now is probably a matter of user demand. If you are a user, go ask your wallet of choice to support the aliasing scheme you prefer.
If you are a developer, consider providing extra quality to your users - CashAccounts is a very easy to pick up protocol and it should only take you a few days to get it integrated from a technical standpoint.
*Want to get involved? reach out to me on* *discord**,* *twitter* *or just write a comment below.* https://discord.gg/9kACN9t https://twitter.com/monsterbitar
Can we get native transaction introspection on Bitcoin Cash?
In the November 2018 upgrade of Bitcoin Cash, a new feature was added that allows developers to verify external signatures provided to a transaction. This in turn opened up the doors to do what is called transaction introspection, where a transaction on the network can enforce spending rules based on the transaction information itself, such as who the recipient can be and how much it can spend.
Unfortunately, due to various restrictions this support can only verify some of the transaction data, has a significant operational cost and requires a deep understanding of how the Bitcoin Cash transaction signature model works.
A better way
Instead of making developers go through a re-verification trick in order to obtain limited information about a transaction it is possible to add a new feature to the protocol that gives developers direct, safe and easy to understand access to relevant contract data. https://read.cash/@pein/bch-covenants-with-spedn-c1170a02
By adding **native** introspection to the protocol, we would reduce implementation risk, reduce transaction complexity and empower developers to build new usecases.
Before adding new features to Bitcoin Cash, it is important to properly evaluate what the impact of such features will be and make sure that relevant stakeholders are aware of and have the opportunity to take part in the development process.
That said, every proposal has to start somewhere, and currently we have set up a working group consisting mainly of node and library developers and are in the process of evaluating the technical feasability and what impact different implementation options might have for the Bitcoin Cash network.
Cost, Benefit and Demand Evaluation
As a step in the process to build consensus and get a proposal implemented I have written up an assessment of the idea, it's impact on the network and who the stakeholders are. This should be seen as an initial draft and I invite interested parties to reach out to me to talk about their views and needs when it comes to transaction introspection so we can make better decisions, together.
Initial cost to the network
Native introspection will use up some of the currently available opcodes. Depending on implementation detail, this cost might be small (single opcode, templated data) or it might be significant (every transaction data can be accessed through a unique relevantopcode).
Since this would be a consensus change, all node software that validate consensus would need to implement the feature.
A limited number of libraries and developer tools that offer advanced scripting functionality would need to implement the feature. Wallets, mining pools, exchanges and services does not have to be updated and will continue to function as normal.
Ongoing cost to the network
Adding native introspection could increase complexity for any future technical changes to the Bitcoin Cash transaction format.
Benefit to the network
Reduces barriers to entry for new developers that want to build smart contracts using transaction introspection.
Improves contract safety by eliminating implementation risks that comes with the complexity of the current re-verification trick used as a workaround.
Allows for new usecases to be developed as native introspection can provide more information on a transaction than the current re-verification trick.
Allows for larger and more complex smart contracts to be developed as native introspection takes up less scripting space compared with current re-verification trick.
For transactions that uses introspection, the transaction size can be reduced which lowers the cost on the network in terms of bandwidth and long-term storage.
For transactions that uses introspection, the network processing cost would be reduced since there is no longer any need to do an additional signature verification.
Existing demand in the network
General Protocols made AnyHedge, a volatility risk-trading contract.
bitjson created CashChannels, reccuring payments for Bitcoin Cash. https://gist.github.com/bitjson https://blog.bitjson.com/cashchannels-recurring-payments-for-bitcoin-cash-3b274fbfa6e2
haryu703 created Hamingja, a loyalty points system using non-tradable SLP token. https://github.com/haryu703 https://github.com/SLPVH/hamingja
Licho have created a Last Will contract to manage inheritence. https://github.com/KarolTrzeszczkowski https://github.com/KarolTrzeszczkowski/Electron-Cash-Last-Will-Plugin
Licho also created Mecenas, a smart contract for recurring payments. https://github.com/KarolTrzeszczkowski https://github.com/KarolTrzeszczkowski/Mecenas-recurring-payment-EC-plugin
Tobias Ruck created be.cash, a refillable, offline wallet in the form of a credit card.
Casues Cash built an modified Mecenas to support recurring payments in USD. https://gitlab.com/bchplease/causes.cash/-/tree/master/contracts
p0oker created an SLP Vending contract that mints tokens on-demand. https://twitter.com/p0oker https://github.com/p0o/yield-farming-bch-smart-contract
Mistcoin has produced minable SLP tokens. https://mistcoin.org/
Future demand in the network
Flipstarter was researching funding contracts as a way to improve usability, which may be possible with better introspection.
General Protocols are looking to build more non-custodial services and can enable more usecases with better introspection.
haryu703 is working on an SLP swap/trading contract. https://github.com/haryu703
Licho is considering to implement traditional games, like NIM. https://github.com/KarolTrzeszczkowski https://en.m.wikipedia.org/wiki/Nim
Tobias Ruck is looking into a non-custodial on-chain gambling product.
James Cramer is experimenting with SLP Mint Guard, to protect minting batons. https://twitter.com/James_Cramer https://github.com/simpleledger/Electron-Cash-SLP/blob/cashscript-dev/lib/cashscript/slp_mint_guard.cash
James Cramer is experimenting with SLP Vault, to help reclaim unclaimed tokens. https://twitter.com/James_Cramer https://github.com/simpleledger/Electron-Cash-SLP/blob/cashscript-dev/lib/cashscript/slp_vault.cash
James Cramer is experimenting with making tokens with minting schedules. https://twitter.com/James_Cramer https://github.com/simpleledgerinc/slp-mint-contracts
James Cramer is experimenting with SLP Dollars, tokens freezable by the issuer. https://twitter.com/James_Cramer https://github.com/simpleledgerinc/cashscript/blob/master/examples/slp_dollar.cash
p0oker is building a BCH staking contract that mints tokens over time. https://twitter.com/p0oker
p0oker is also building an SLP exchange contract to sell NFTs. https://twitter.com/p0oker
Current opposition from the network
There is currently no known opposition to native introspection.
Costs for delay / stagnation
Continued use of the inefficient re-verification trick makes the blockchain larger than it needs to be and could have a negative impact on initial block download times and storage requirements.
Requirement to use a difficult technical workaround in order to achieve transaction introspection could result in loss of opportunity as development costs and barrier to entry remains high.
Complexity of the technical workaround in order to achieve transaction introspection could result in otherwise successful businesses having technical problems with their implementation that results in loss of profits and damages reputation of both the company and Bitcoin Cash as a network.
Some applications and usecases are not possible with the re-verification trick but depending on technical implementation details may be possible with native introspection, not serving these usecases on BCH might result in competitors building these products and gaining theses users instead.
Where do we go from here?
The next step from here is to write a formal draft proposal and engage with a broader set of stakeholders. If you have a need or interest in native introspection, or have a strong opinion on why native introspection should be rejected, you're welcome to join us and make your voice heard on our Telegram group. https://t.me/transactionintrospection
Formalize an alternative unit and ticker name for 1/1,000,000th of a Bitcoin Cash.
We're soon past 2020 and it has been more than a decade since the introduction of Bitcoin. In the years that have passed, we have had countless users tell us that it is difficult and frustrating to adapt to some of Bitcoins peculiarities:
Some believe they can't afford a whole Bitcoin
Many have difficulty relating to what 0.00001645 is worth
Payment registers and bookkeeping doesn't support Bitcoin
Displaying small prices takes up a lot of space (think: `₿ 0.0000507` vs `$1`)
All of the issues above share a common problem and represent significant friction against adoption in commerce. For people who only **wants to speculate on value gains**, this is not a problem, but for those who want to transition to a world where crypto is the predominant payment system and the unit of account to get a stable and globally accessible currency I believe **we need to address this.**
If we are to be successful, we should build our tools and services to work well in a world in which we are successful. In such a world, Bitcoin Cash will have a higher valuation, and this decimal problem will be worse than it is today.
*Humans are not good at relating to small decimal numbers.*
So lets break down the simplest way in which we can make this change easy and relatable. Just like we added "Cash" to Bitcoin, I suggest we add "Cash" to the Bit unit, to get Bitcash. This is already how many people, new users in particular, naturally talk about Bitcoin Cash and you can see a clear example here: https://www.youtube.com/watch?v=vq_GK2ms5Ps&feature=youtu.be
Taking it one step further, if we assign the ticker `XCH` to the `Bitcash` unit we end up with something that address the problem above, while being compliant with the expectations of registers and bookkeeping applications.
I can get down and explain how and why in gritty detail, but I think the problem right now isn't that we don't have the information, but rather that we're **lacking the agency to act**. As such, I will instead link to a presentation by Andrew Clifford re-iterating that we have a problem here: https://youtu.be/TIQUmFH_I-4?t=307
**Remember**: if we don't serve our users well - we will fail to get adoption.
The Road to AnyHedge
Have you ever wondered what it takes to build a smart contract financial product on Bitcoin Cash? In the first half of 2019 I joined a small team to build a non-custodial futures contract, or at least try and see what is possible and what is not.
*This article will outline my part of the story leading up to the AnyHedge launch in 2020.*
Where it started
I wasn't part of the team when the idea was first formalized in March of 2019 and the first draft of a contract was successfully compiled using an early version of Spedn, but I joined soon after to help build the tools required to use the contract. https://spedn.pl/
*We worked on our own time and without funding, but the interest from a possible investor at this point was a signal that we were working on what might one day become a profitable company.*
Early adopter issues
Building blindly
To build smart contracts on Bitcoin Cash requires an understanding of not only the scripting language, but also transaction signing and protocol structures and limitations.
Not long after I had started working, I discovered that there was no good source of information anywhere. I had to go read Bitcoin (BTC) documentation, which was often wrong due to being updated for BTC, or because BCH had diverged from it. I also had to read and try to understand node upgrade specifications to learn how Bitcoin Cash functioned differently, which only lists the changes and frequently referred back to "same as before", with no references to any sources of what was before.
Working with poor documentation is **difficult** and **unproductive**, so I wrote the BUIP121 proposal to Bitcoin Unlimited to help build better public documentation for developers who need to interact with the protocol. https://bitco.in/forum/threads/buip121-passed-create-formal-bch-specifications.23762/
*While not perfect today, the work done by* *Bitcoin Unlimited* *and* *Bitcoin Verde* *has given new developers access to* *better documentation* *than we had before.* https://www.bitcoinunlimited.info/ https://bitcoinverde.org/ https://documentation.cash/
Building wildly
In the months after I joined we each did our best to make progress, but work was slow and intermittent for various reasons. With the help of our potential investors, I was able to go to Townsville ahead of the Bitcoin Cash City Conference and meet up with the team. https://2019.bitcoincashcity.com/
At this point, work really took off and in a matter of weeks we went from having a non-functional draft contract, to successfully funding and redeeming the first AnyHedge contract on-chain.
During the conference in September 2019 we held our **first demonstration** to potential partners and investors and got our first verbal agreement to integrate with an exchange.
*It was hacky. It was blunt. It was messy.*
*The tools we relied on were unfinished and buggy (as evident by 0.1.x version numbers), but with the help of the fantastic* *Meep transaction debugger* *from the* *BCHD* *team we eventually managed to go from idea, to proof of concept.* https://github.com/gcash/meep https://bchd.cash/
Broken bridges
Unreliable REST APIs
We built our tooling on the best-known and best documented developer stack that was available to us, the BitBox SDK and related REST API. It served us well in the prototyping phase, but at the end of 2019 it became apparent to us that it was not sustainable to build financial commercial projects on public free infrastructure. https://developer.bitcoin.com/bitbox/ https://rest.bitcoin.com/
We looked at many alternatives and eventually settled on using Electrum servers as our backend. The Electrum protocol is not perfect, but since it powers the Electron Cash wallet and has multiple server software it is likely to stay maintained going forward.
Finding good tools to interact with the servers turned out to be problematic, though. Most were no longer maintained, or didn't support the features we needed. We built the electrum-cash library that supports all features of the electrum protocol, including encryption, websockets and automated version negotiation. https://www.npmjs.com/package/electrum-cash
*The electrum-cash library is now used by many actors in the ecosystem, for example* *flipstarter**,* *mainnet**,* *fullstack* *and* *cashscript**. We have also* *made a commitment* *to financially support the infrastructure we depend on and have a* *public sponsorships* *that will grow in size as we grow in revenue.* https://flipstarter.cash/ https://mainnet.cash/ https://fullstack.cash/ https://cashscript.org/ https://read.cash/@GeneralProtocols/sponsorship-in-the-bitcoin-cash-ecosystem-5f2db5e0 https://generalprotocols.com/#sponsorships
Who do you partner with if you're the first?
The AnyHedge contract has two contract parties, and an oracle they trust to provide pricing information. From the start, we wanted to use a 3rd party oracle, but what do you do when you're the first one to the scene and there's no one else to partner up with?
We talked with many companies such as Bitpay, Chainlink, Coin Dance, Blockchair and CoinGecko, who either have a good source for price data, or provide services using price data. Unfortunately due to different infrastructure needs from ETH and the fact that BCH smart contracts were unproven in the market, it was not yet compelling enough for them to invest resources in a BCH oracle. https://bitpay.com/ https://chain.link/ https://coin.dance/ https://blockchair.com/ https://www.coingecko.com/
We then tried to collaborate with other developers to set up standards and documentation so that if we had to build it ourselves, we would at least be building something that is reusable and valuable to others, but this effort also fell flat as there was no one else building smart contracts that had a usecase for the kind of oracle that we needed.
*We then built a* *price-oracle library* *and an* *oracle service* *that is publicly available to other builders in the Bitcoin Cash ecosystem. In the future, we will re-engage the discussion and try to find external partners to run the price oracle services.* https://www.npmjs.com/package/@generalprotocols/price-oracle https://read.cash/@GeneralProtocols/anyhedge-beta-is-live-0b4e9379
Funding woes
Having met with our potential investors we felt we had good alignment and we worked together to build a businessplan, shareholders agreement and other paperwork.
After some months it turned out that due to changes in expectations the requirements from the investors was changed and we had a falling out.
It was really painful to go back to the uncertainty with regards to funding at this time as we didn't know if we'd ever have another chance.
*At this point, we had been self-funded for 9 months already and we had to set up plans for how far we were willing to go before deeming the project a failure.*
New year, new troubles
The Infrastructure Funding Plan
At the start of 2020, Jiang Zhuoer announced his intent to fund infrastructure via coinbase reward. The proposal had some initial positive reception as it was easy for most people to see the good that extra funding could accomplish, but after a few weeks it was clear that the costs of the IFP were unacceptable. https://medium.com/@jiangzhuoer/infrastructure-funding-plan-for-bitcoin-cash-131fdcd2412e
Despite the concerns raised, though, Bitcoin ABC officially added a version of the IFP to their codebase and set it to be miner-activated ahead of the may upgrade. https://www.bitcoinabc.org/2020-02-15-miner-fund/
*As none of us on the team wanted to work on a coin we didn't believe in, we now had to make a choice - either disband, or solve the underlying funding problem..*
Building Flipstarter
Seeing that the Bitcoin Cash ecosystem was at risk, and that we had built our product on it, the company shifted all available resources to address the funding problem.
We took some time to listen and found out that one of the major problems was the free-rider or unfairness aspect of voluntary donation, where some miners who have supported the ecosystem financially were unhappy that others have benefitted without supporting anything at all.
After a month of working non-stop, Flipstarter was unveiled as a non-custodial assurance contract fundraising tool, and later on successfully raised $500k to fund infrastructure. https://read.cash/@flipstarter/introducing-flipstarter-695d4d50 https://read.cash/@flipstarter/flipstarter-500k-is-a-success-now-the-real-work-begins-c05253a3
*While we spent almost two months working full-time on Flipstarter, it was a community effort and with the help of all who contributed to it, a* *wide range of projects* *has already raised more than 5,000 BCH (~$1.2 million USD at the time of campaign completion).* https://flipstarters.bitcoincash.network/#/
Bitcoin Cash Node
While I was focusing almost exclusively on coding for Flipstarter, other members of the team also helped with the set up of the first fork of Bitcoin ABC as a contingency plan and drop-in replacement for miners who wanted to oppose the IFP. https://bitcoincashnode.org/
A serious, responsible company
After having shown that the IFP wasn't the only possible way to resolve funding, we returned to building on AnyHedge and by mid-2020 we were once again moving forward at a respectable pace and making good progress.
Whitepaper
We released the AnyHedge Whitepaper, outlining the contract structure and explaining how you can trade volatility risk to achieve value stability without leaving the Bitcoin Cash ecosystem. https://anyhedge.com/downloads/AnyHedge%20Whitepaper.pdf
Numerical analysis
We completed a collaboration with Karol Trzeszczkowski and released a numerical analysis of the AnyHedge smart contract. https://github.com/KarolTrzeszczkowski https://anyhedge.com/downloads/AnyHedge%20Numerical%20Analysis.pdf
Simulator
To help traders better understand the contract behaviour, we built and released an online contract simulator. https://anyhedge.com/how-it-works/#simulator
Secured funding
During the time we worked on Flipstarter and BCHN we built new relations and we found ourselves in contact with new investors. Having shown our ability to execute on the plans we had laid forward, we secured our first round of investment of over 1 million USD. https://read.cash/@GeneralProtocols/bch-defi-startup-general-protocols-raises-over-1-mil-5e6d4317
Can we cancel 2020, please?
We were finally back to building on AnyHedge again. Our automated settlement service was taking shape nicely and just as we were starting to focus on the exchange integration, we again got the rug pulled out from under us without warning.
Grasberg
In July 2020, Bitcoin ABC decided to shock the ecosystem by announcing their own DAA replacement, despite existing ecosystem-wide collaboration and convergence on a different algorithm. The Grasberg DAA would drastically change the expectations on block production with its past-drift correction. https://blog.bitcoinabc.org/2020/07/23/announcing-the-grasberg-daa/
Having built our oracle and contract infrastructure on the now decades old expectation that Bitcoin, on average, produces one block per 10 minutes we found ourself scrambling to emergency meetings to understand the implications.
Upon realizing that it would likely result in a redesign of our oracle and contract structures, and would delay us to market by months, we decided that this was not acceptable and issued a joint statement with our partners on the matter. https://read.cash/@GeneralProtocols/joint-statement-on-aserti3-2d-algorithm-f98f0a2c
I reached out directly to Amaury at Bitcoin ABC and explained that this would have serious and damaging implications for us. He told me that it would be best if I adapted to the new rule, stating that it was necessary to change the emissions schedule (to make it predictable) in order to demonstrate a commitment to not changing it.
*Seeing as almost all people we could reach in the ecosystem were discontent with both the Grasberg changes to established expectations, and the reckless and* *frankly disrespectful* *way that Bitcoin ABC had pushed out the DAA change, we chose to collaborate with and help produce an* *ecosystem-wide joint statement* *in favor of the* aserti3-2d *DAA.* https://read.cash/@jtoomim/dark-secrets-of-the-grasberg-daa-a9239fb6#5-a-concrete-proposal-had-reached-abc-at-the-time-of-their-writing https://read.cash/@sha256_88ebd526/bitcoin-cash-bch-november-2020-upgrade-statement-f7c03159
Return of the IFP
Despite the previous hard position, in just a handful of weeks Bitcoin ABC backed down with regards to the Grasberg DAA, but in a tantrum instead laid down an ultimatum to implement the IFP. This version came with entirely new numbers and again involved unknown entities that were to be in control the funds and clearly stated that it was "not an invitation to debate".
Talking with people made it obvious that this was the straw that broke the camels back, and we would see Bitcoin ABC force a split of the network in the coming hardfork.
As a company trying to build a product, we need a userbase to sell our product to. If we continue splitting our network effect over and over there'll be no customers left for us, and we will have failed.
*Thankfully, we had already demonstrated via Flipstarter that there were viable alternatives and while we still spent a lot of time building relationships and keeping people informed about the possible outcomes, it wasn't as bad as the first time.*
Summary of the journey along the road to AnyHedge
We are now in the end of 2020, and what I estimated would be a handful of months of work ended up taking almost two years. It shouldn't have been this difficult and the lack of developer resources and developer infrastructure has likely been a significant contributor to the current price of Bitcoin Cash.
The good part is that a lot of the problems we encountered no longer exist - the smart contract tooling is getting mature, the documentation is getting better, infrastructure is getting funded and once AnyHedge demonstrates that there is profitable opportunity to be had building non-custodial financial products I expect new teams and companies to enter the space and grow together with us.
*As for the product itself we're over the finish line and AnyHedge will soon go out of beta and launch with the* *Detoken* *non-custodial exchange.* https://detoken.net/
I have release v2.0.3 of Electrum-cash, a quality and bug-fix release:
Fix regression issue with automatic reconnection.
Fix issue where initial connect would never reject on failure.
Fix issue where a failed version negotiation didn't result in error.
Fix so that servers added to a cluster automatically restore subscriptions.
Add support for SNI (get correct certificate for multi-domain servers)
Random thoughts on parenting: control and influence over others.
When you are a baby, you don't know where the extent of your power begin and ends:
When you are hungry, you flex your I-am-hungry-muscle, and food is delivered into your mouth.
When you drop your toy, you flex your I-want-my-toy-back muscle and the toy is brought back to you.
Eventually, as people **misunderstand**, **misjudge** or **reject** your expressed desires, you will come to realize what is within your control, and what is not.
However, this process is never complete and you will strive to exert influence over other entities for the rest of your life.
Being able to extend your control over another entity **can be useful**:
a magician can misdirect your attention to induce wonder and curiousity.
a teacher can bring awareness by controlling attention and narrative.
a civil rights activist can rally support and change society for the better.
But it can also be **dangerous**:
adults trying to exert control over children can lead to child abuse.
lovers trying to exert control over their partners can lead to domestic abuse.
spiritual leaders trying to exert control over their followers can lead to cult-like abuse.
The tools available to exert influence are many.
Which tool you use in order to influence others is important and often shapes the outcome for the people involved:
some are often positive, such as **inspiration**, **education** and **promises**.
some are mostly negative, for example **guilt**, **shame**, **fear** and **threats**.
some heavily depend on context, like **force** and **trust**.
*There's a saying that when you're a hammer, everything looks like a nail.*
The children in the shopping mall who prevent the robot from functioning may be exerting their influence and gaining experience in using tools that are likely to be negative for those they influence in the future.
https://www.youtube.com/watch?v=CuJT9EtdETY
Providing training and experience in using tools that help you exert influence over others allow for using the right tool for the job, which increases the odds of success - but success is not always a positive outcome.
*For example, dictators have successfully destroyed millions of lives.*
As parents and members of society, we can choose how we react to children experimenting with such tools, and can help set expectations and build experience with outcomes that impact when and how often the children will use those tools in the future.
It is important that we are consistent though, as if we reject the usage of a tool in one context, but then use it ourselves in another we risk creating outcomes like domestic abuse, where the negative tools are only used in situations where one can avoid punishment due to privacy.
Ultimately though, children in modern society learn from a wide range of experiences and interactions. Even if it's not your own children, and even if it only for an isolated occurence, you can still help shape a future less dependent on tools that have strong negative associations by encouraging use of positive tools to influence others, and setting clear boundaries and expectations on usage of the tools that can have a negative outcome.
***Disclaimer:*** *This is my current understanding of the subject above, and may change as I learn more about the world around me. I am neither a professional psychologist nor do I have any formal education on the subject matter.*
v2.0 of `electrum-cash` released.
Quality fixes, bug fixes and some new features, most importantly **websocket** support:
https://gitlab.com/GeneralProtocols/electrum-cash/-/tags/v2.0.0
Adding a bunch of crap text at the end here because read-cash don't want "too similar" content.
Beta Price Oracle: Requesting current price
Introduction
We at generalprotocols are running a public beta of a Price Oracle that is used for our AnyHedge product. This article will show you how to use the `@generalprotocols/price-oracle` **NPM** library to connect with the price oracle, request the latest price message, verify the message signature and finally parse the price message to get to the price data. https://www.generalprotocols.com/ https://read.cash/@GeneralProtocols/anyhedge-product-overview-0b4e9379 https://www.anyhedge.com
Setting up
Install the library so that it is available in your project:
npm install @generalprotocols/price-oracle
Include the library parts you will be using, and choose which oracle service provider to use (our beta is hosted at `oracles.generalprotocols.com`) and which oracle you want to get data for (our beta oracle uses the public key below):
// Import the Price Oracle library.
const { OracleData, OracleNetwork, OracleProtocol } = require('@generalprotocols/price-oracle');
// Choose which oracle to use, and what service provider to use to get the oracle data.
const oracleAddress = 'oracles.generalprotocols.com';
const oraclePublicKey = '0273ee49099f0a09be514cbb45756bf49ad256d0a6de993107e98c89c16b6fa84e';
Requesting the current price
To get the most recently issued price message, first form a request structure, then send the request to the oracle service provider:
// Create a request for the most recently issued price message, for the given oracle.
const requestString = { action: 'latest', public_key: oraclePublicKey };
// Send the request to the oracle service provider, indexing the given oracle data.
const response = await OracleNetwork.request(requestString, oracleAddress);
*The response is an object that looks like this:*
message: <Buffer df 77 00 00 42 e1 09 00 00 00 00 00 00 00 00 00 ...>,
public_key: <Buffer 02 73 ee 49 09 9f 0a 09 be 51 4c bb 45 75 6b f4 ...>,
signature: <Buffer 31 9f ee dd 7a 19 45 57 dc 3b c0 1d 7f 74 c4 92 ...>
Validating message signature
When you have the response, you should validate that it is signed by the oracle that you requested. Simply call the library function and pass in the message and signature you got in the response, but use the same oracle public key as before so you can be sure the data provided is for the oracle you expect:
// Verify that the signature provided matches the oracle message and public key.
const validity = await OracleData.verifyMessageSignature(response.message, response.signature, Buffer.from(oraclePublicKey, 'hex'));
*The value returned will be a boolean indicating the validity of the signature.*
true
Parsing price message
After you've made sure that the message is properly signed, you can parse it to get the data stored within the message which you can then use in your application:
// Parse an oracle price message into parts.
const messageParts = await OracleData.parsePriceMessage(response.message);
*The returned value is an object with the following properties:*
price: 30311,
blockHeight: 647491,
blockHash: <Buffer 00 00 00 00 00 00 00 00 00 a9 d6 af a6 bc 32 ...>,
blockSequence: 1,
oracleSequence: 60427,
timestamp: 1596903497
electrum-cash: strategic use of clusters
Introduction
**Electrum-cash** is a javascript/typescript library for communicating with electrum servers. https://www.npmjs.com/package/electrum-cash/library
This article will showcase some common ways you can set up and configure clusters as well as give some examples for when you might want to use each setup.
Available configuration options
Before we look at the various setups, it is helpful to understand the terminology and parameters. In the context of this library we define the following terms:
**Cluster**: A list of electrum servers to use.
**Confidence**: Number of servers that need to be in agreement before we use their data.
**Distribution**: How many of the available servers we select to request data from.
**Ordering**: How we select which of the available servers to request data from.
The default settings
If you try to create a cluster and does not configure the settings, you will have a confidence of `1` so you will trust any server and get a dynamic cluster distribution of `ALL` which means that the cluster will be ready as soon as any server is available. The ordering is less important since requests will be sent to all servers, but is set to `RANDOM`.
*The benefit of this approach is that it provides low latency and as such is well suited during development of your project, and also provides a good user experience.*
// Initialize an electrum cluster using the default 1-of-ALL strategy.
const electrum = new ElectrumCluster('Your Electrum App Name', '1.4.3');
Hiding the big picture
When you send requests to your cluster, the servers you send to can learn information about your usage which might be undesirable. While it's not possible to both get the convenience of 3rd party servers and perfect privacy at the same time, you can configure your cluster to gain some privacy by not sending all requests to the same few servers.
To do so, you should set a **low confidence** and use a **large number of servers** with a **low and random distribution**.
*The benefit of this approach is that it's very unlikely that any server will be able to fully track your usage. Sadly, it also means that it's possible to randomly send to high-latency servers which has an impact on the user experience.*
// Initialize an electrum cluster with a 1-of-1 privacy-oriented strategy.
const electrum = new ElectrumCluster('Your Electrum App Name', '1.4.3', 1, 1);
// Add as many servers as possible
electrum.addServer('electrum.imaginary.cash');
...
Avoiding issues by consensus
When you are using multiple servers there is a chance they will not agree about the state of the network. It could be due to simple things like one server just having gotten a new block another server is not yet aware or, an accidental chainsplit where the servers consensus code made them follow different chaintips. It could also be due to the server operator being hostile and trying to defraud naive applications that trusts them without verifying the information.
It's recommended that you should always verify all information you are able to, but sometimes you just don't want bad data to begin with, in which case you can configure your cluster to require a **higher confidence** and then either using a **random distribution**, or a **prioritized distribution** with **trusted servers** added first.
*The benefit of this approach is that no single server that gets compromised can cause your application to act on bad data, which reduces that attack surface of your application.*
// Initialize an electrum cluster with a 2-of-3 consensus-oriented strategy.
const electrum = new ElectrumCluster('Your Electrum App Name', '1.4.3', 2, 3, ClusterOrder.RANDOM);
// Initialize an electrum cluster with a 2-of-3 consensus-oriented strategy.
const electrum = new ElectrumCluster('Your Electrum App Name', '1.4.3', 2, 3, ClusterOrder.PRIORITY);
// Add trusted servers first..
electrum.addServer('electrum.imaginary.cash');
electrum.addServer('bch.imaginary.cash');
// ..then as many backup servers as you want.
electrum.addServer('electroncash.de');
electrum.addServer('electroncash.dk');
Conclusion
By using `electrum-cash` clusters, you get automatic fail-over, automatic re-connection after outages and by choosing your **confidence** and **disitribution** strategy, you can choose how you want to balance **performance**, **reliability** and **privacy.**
electrum-cash: how to use a cluster with multiple servers
Introduction
**Electrum-cash** is a javascript/typescript library for communicating with electrum servers. https://www.npmjs.com/package/electrum-cash/library
This example demonstrates how to create and connect to a cluster of servers, wait for the cluster to get ready, respond to changes in the cluster status and shut down the cluster when you're done using it.
Including the cluster library in your project
When you are using multiple servers for your project, you should include the cluster, either in `CommonJS` or as an `ES2015 module` depending on your project.
// Import the electrum client in CommonJS.
const { ElectrumCluster } = require('electrum-cash');
// Import the electrum client as an ES2015 module.
import ElectrumCluster from 'electrum-cash';
Set up the library and add servers to your cluster
You will need to create an instance of the electrum cluster with an optional distribution and confidence strategy and then add as many servers as you want. https://generalprotocols.gitlab.io/electrum-cash/library/ElectrumCluster.html
*We use the default 1-of-all strategy here, and will cover alternatives in a future articles.*
// Initialize an electrum cluster.
const electrum = new ElectrumCluster('Your Electrum App Name', '1.4.3');
// Add some servers to the cluster.
electrum.addServer('bch.imaginary.cash');
electrum.addServer('electroncash.de');
electrum.addServer('electroncash.dk');
electrum.addServer('electron.jochen-hoenicke.de', 51002);
electrum.addServer('electrum.imaginary.cash');
Waiting for the cluster to be ready
Before you can start using the cluster, you need to wait for the required number of servers to connect and complete version negotiation.
// Wait for the cluster to become ready for use.
await electrum.ready();
Detecting cluster outages
The `electrum-cash` library automatically reconnects and tries to keep you connected to the servers at all times. However, outages are sometimes unavoidable and if one or more servers in your clusters become unavailable your cluster can be degraded or disabled.
To log a message when your cluster becomes degraded, listen for the `degraded` signal.
// Write to the console log when the cluster is degraded.
electrum.on('degraded', console.log.bind(null, 'cluster is degraded'));
To detect when your cluster us unusable, listen to the disabled signal.
// Function that will handle when cluster is disabled
const handleClusterOutage = function()
{
// Handle the outage by pausing activites that require network or similar.
}
// Listen for cluster disable events.
electrum.on('disabled', handleClusterOutage);
To detect when your cluster status is automatically restored, listen to the `ready` signal.
*Note that the ready signal is also emitted when the cluster initially becomes available.*
// Function that will act when the cluster becomes available.
const handleClusterRestoration = function()
{
// The cluster is at a good state.
}
// Listen for cluster ready events.
electrum.on('ready', handleClusterRestoration);
Shutting down when you're done
After you are done with the cluster, you should ask all connections to shut down gracefully.
// Close all connections gracefully.
await electrum.shutdown();
electrum-cash: debugging problems and reporting issues
Introduction
**Electrum-cash** is a javascript/typescript library for communicating with electrum servers. https://www.npmjs.com/package/electrum-cash/library
This example demonstrates how to enable debug output, control what debug messages to show and where to submit bug reports.
Sample application
For this article, we will be using a small and simple application that connects to a server, subscribes to notification for given address, waits 10 seconds and then shuts down.
// Include the electrum-cash library in our project.
const { ElectrumClient } = require('electrum-cash');
// Wrap the application in an async function to allow async/await.
const main = async function()
{
// Initialize an electrum client.
const electrum = new ElectrumClient('Electrum client test', '1.4.3', 'bch.imaginary.cash');
// Wait for the connection to be ready and version negotiation to complete.
await electrum.connect();
// Log address change notifications for ☯ jonathan#100 <qr4aadjrpu73d2wxwkxkcrt6gqxgu6a7usxfm96fst>
await electrum.subscribe(console.log, 'blockchain.address.subscribe', 'qr4aadjrpu73d2wxwkxkcrt6gqxgu6a7usxfm96fst');
// Disconnect after 10 seconds.
setTimeout(electrum.disconnect.bind(electrum), 10000);
}
// Start the application.
main();
Enable debug output
The `electrum-cash` library uses the debug library to manage log output. To enable all debug logs, simply start the application with `DEBUG="*"` prepended to the command line or set as an environment variable. https://www.npmjs.com/package/debug
*Note: this also enables debug output for all other components that use the* `debug` *library.*
$ DEBUG="*" node example.js
Configure what output to show
The `electrum-cash` library can enable or disable specific types of output. Set the `DEBUG` environment variable to a list of entries separated by commas, and to exclude output, prepend the entry with a minus sign.
For example, to show all electrum-cash output, but not the keep-alive `pulse` entries:
$ DEBUG="electrum-cash:*, -electrum-cash:pulse*" node example.js
*In order to keep the log output aligned, some of the log names currently end with one or more spaces, and as such you might need to end the log name with a wildcard symbol.*
List of available outputs
The `electrum-cash` library currently have **6** different output types:
**Warnings** and **Errors:** Messages that inform you when things can or have gone wrong.
**Network**, **Client** and **Cluster**: Provides insight into how the library operates.
**Pulses**: Prints a log message when we send a message to keep the connection alive.
Reporting bugs and issues
If you have come across a bug or are having a problem with the `electrum-cash` library, please let us know. Go to the repository issues page to see if we are already aware of your situation, and make a new issue if you want to. https://gitlab.com/GeneralProtocols/electrum-cash/library/-/issues

electrum-cash: connecting to a server
Introduction
**Electrum-cash** is a javascript/typescript library for communicating with electrum servers. https://www.npmjs.com/package/electrum-cash/library
This example demonstrates how to create a connection to a server and how to cleanly shut down when you're done using it.
Including the client library in your project
When you are using a single server for your project, you should only include the client, either in `CommonJS` or as an `ES2015 module` depending on your project.
// Import the electrum client in CommonJS.
const { ElectrumClient } = require('electrum-cash');
// Import the electrum client as an ES2015 module.
import ElectrumClient from 'electrum-cash';
Set up the library and connect with a server
You will need to create an instance of the electrum client with the server connection electrum clientdetails for the server you want to use. https://generalprotocols.gitlab.io/electrum-cash/library/ElectrumClient.html
// Initialize an electrum client.
const electrum = new ElectrumClient('Your Electrum App Name', '1.4.3', 'bch.imaginary.cash');
Waiting for the connection to be established
Before you can start using the client, you need to connect to the server and wait for it to complete version negotiation.
// Wait for the client to connect and complete version negotiation.
await electrum.connect();
Shutting down when you're done
After you're done with the server, you should disconnect from it to shutdown gracefully.
// Close the connection.
await electrum.disconnect();
electrum-cash: getting started
Introduction
**Electrum-cash** is a javascript/typescript library for communicating with electrum servers. https://www.npmjs.com/package/electrum-cash/library
This example demonstrates how to install the library with `npm` and how to include it in your `NodeJS`-based project.
*It is possible to use the library in a browser and on other platforms by transpiling with tools like* `babel`*,* `webpack` *and similar, but that is outside the scope of this article.*
Requirements
Before you get started, make sure that you have reasonable modern versions of `nodejs` and `npm` installed by opening a terminal prompt and requesting version information:
$ node -v
v14.4.0
$ npm -v
6.14.5
Installing the library
To install the `electrum-cash` library, navigate to your project's root folder and use `npm`:
$ cd MyProject/
$ npm install electrum-cash
Import the library into your project
The library supports both `CommonJS` and `ES2015`, and comes with bindings for `TypeScript`.
*This example includes the full library but you can also include just the parts you need.*
// Include the electrum-cash library using CommonJS.
const ElectrumCash = require('electrum-cash');
// Include the electrum-cash library as an ES2015 module.
import * as ElectrumCash from 'electrum-cash';
Conclusion
As long as you have a modern version of `NodeJS` you should be able to add `electrum-cash` to your project in just a few minutes.
v1.2.0 of `electrum-cash` released. Plenty of quality fixes and some new features to:
https://gitlab.com/GeneralProtocols/electrum-cash/-/tags/v1.2.0
electrum-cash: working with transaction history
Introduction
**Electrum-cash** is a javascript/typescript library for communicating with electrum servers. https://www.npmjs.com/package/electrum-cash/library
This example demonstrates how to get a list of all transactions for a given address and notifications when the transactions are updated, using `v1.4.3` of the electrum protocol.
*To keep the example simple and clear, the code to set up and close a connection is omitted.*
Fetching transaction history
To get the transaction history, send a `blockchain.address.get_history` **request** with the address as the first parameter.
// The address we want to get history for.
const address = 'qr4aadjrpu73d2wxwkxkcrt6gqxgu6a7usxfm96fst';
// Request the transaction history from the server.
const transactionHistory = await electrum.request('blockchain.address.get_history', address);
// Count the number of confirmed and unconfirmed transactions.
const confirmedCount = transactionHistory.filter((entry) => entry.height > 0).length;
const unconfirmedCount = transactionHistory.filter((entry) => entry.height <= 0).length;
// Log the history information
console.log(`There are ${confirmedCount} confirmed and ${unconfirmedCount} unconfirmed transactions on '${address}'.`);
console.log(`The first transaction was in block #${transactionHistory[0].height} with transaction '${transactionHistory[0].tx_hash}'.`);
*Example output with 1 unconfirmed transaction:*
There are 605 confirmed and 1 unconfirmed transactions on 'qr4aadjrpu73d2wxwkxkcrt6gqxgu6a7usxfm96fst'.
The first transaction was in block #560682 with transaction 'd7820227977fc05170f1c1957453709511fd702f7d608a2f48e450588ad8c5a9'.
Tracking transaction history
To get notifications when the transaction history is updated, **subscribe** to `blockchain.address.subscribe` to get status updates for the address, then request the transaction history.
// Create a function that will handle transaction history updates.
const handleTransactionHistoryUpdates = async function(address)
{
// Request the transaction history from the server.
const transactionHistory = await electrum.request('blockchain.address.get_history', address);
// Log the oldest and newest transactions.
console.log(transactionHistory[0]);
console.log([...transactionHistory].pop());
}
// The address we want to get transaction history updates for.
const address = 'qr4aadjrpu73d2wxwkxkcrt6gqxgu6a7usxfm96fst';
// Subscribe to notifications for updates to transaction history for the given address.
// NOTE: this sends notifications for all changes to the transaction history, not only for new transactions.
await electrum.subscribe(handleTransactionHistoryUpdates.bind(this, address), `blockchain.address.subscribe`, address);
*Example output with one unconfirmed transaction:*
{
height: 560682,
tx_hash: 'd7820227977fc05170f1c1957453709511fd702f7d608a2f48e450588ad8c5a9'
}
{
fee: 230,
height: 0,
tx_hash: 'e2183edcfc4e82be0c09651cf815c223bface0fdf5fc670737ee4d883b2d3f21'
}
Conclusion
Using the `electrum-cash` library makes it easy to get transaction history and to get notifications when that history changes. Tracking what actually changed can be done by comparing previously acquired transaction history with the updated transaction history, but that is out of the scope of this article.
electrum-cash: broadcasting transactions
Introduction
**Electrum-cash** is a javascript/typescript library for communicating with electrum servers. https://www.npmjs.com/package/electrum-cash/library
This example demonstrates how to broadcast a raw transaction and how to get notified of when the transaction gets included in a block, using `v1.4.3` of the electrum protocol.
*To keep the example simple and clear, the code to set up and close a connection is omitted.*
Broadcasting a transaction
To broadcast a raw transaction, send a `blockchain.transaction.broadcast` **request** with the raw transaction hex as the first parameter:
// The raw transaction we want to broadcast.
const transactionHex = '01000000017616e3106ca8e7a92eed190319fea34327edfb0991714444a5cc757000cde21a000000006a473044022007b6e2e864f9807602b9937d25b7df7ffdcd1ff559dad0cc130e9174bfea5cd8022070ae24a132f9420090d878defb17b78db7f15ced5ea4090c2f423d65f0d70d6c412102c94e85aa74899fb9378079e42c0e225c7481689c7fd7b3accd567ddafb53c6acfeffffff026db40600000000001976a914ebdeb6430f3d16a9c6758d6c0d7a400c8e6bbee488acdc120b00000000001976a9142c805fc822ea73b954040d787a8ea69e8d8caf5c88acf5d30900';
// Broadcast the transaction.
const transactionHash = await electrum.request('blockchain.transaction.broadcast', transactionHex);
// Log the transaction hash.
console.log(transactionHash);
*Example output:*
6df81e9abee5702d9c8b0ad941e0c0d663855d2186162fb5e86136d99904c48c
Checking transaction confirmations
To look up transaction confirmations, send a `blockchain.transaction.get` **request** with the transaction hash as the first parameter and set verbose flag as the second parameter to **true**.
// The transaction we want to look up.
const transactionHash = '6df81e9abee5702d9c8b0ad941e0c0d663855d2186162fb5e86136d99904c48c';
// Request verbose transaction details which includes the number of confirmations.
const { confirmations } = await electrum.request('blockchain.transaction.get', transactionHash, true);
// Log the transaction confirmations.
console.log(confirmations);
*Example output when the transaction is still in the mempool:*
undefined
*Example output when the transaction has 4 confirmations:*
4
Listening for transaction block inclusion
To get notification when your transaction is included in a block, **subscribe** to new block notifications with `blockchain.headers.subscribe`, then request the transaction status. Remember to **unsubscribe** when you no longer need the information.
**Disclaimer**: the unsubscribe feature will be included in the v1.2.0 release of electrum-cash https://gitlab.com/GeneralProtocols/electrum-cash/library/-/issues/7 https://gitlab.com/GeneralProtocols/electrum-cash/library/-/issues?milestone_title=v1.2.0
// Create a function that will handle confirmation updates.
const handleConfirmationUpdates = async function(callbackFunction, transactionHash)
{
// Request verbose transaction details which includes the number of confirmations.
const { confirmations } = await electrum.request('blockchain.transaction.get', transactionHash, true);
// If the transaction now have confirmations..
if(confirmations)
{
// Log that the transaction was confirmed.
console.log(`Transaction '${transactionHash}' now have ${confirmations} confirmations.`);
// Unsubscribe from further updates.
// NOTE: we bind the transaction to ensure that it uses the same name as when we subscribed.
electrum.unsubscribe(callbackFunction.bind(this), `blockchain.headers.subscribe`);
}
}
// The transaction we want to look up.
const transactionHash = '6df81e9abee5702d9c8b0ad941e0c0d663855d2186162fb5e86136d99904c48c';
// Subscribe to notifications for new blocks
// NOTE: we bind the transaction to provide the transaction hash to it.
await electrum.subscribe(handleConfirmationUpdates.bind(this, handleConfirmationUpdates, transactionHash), `blockchain.headers.subscribe`);
**Example output when the transaction gets included in a block:**
Transaction '6df81e9abee5702d9c8b0ad941e0c0d663855d2186162fb5e86136d99904c48c' now have 1 confirmations.
Conclusion
Broadcasting a transaction with `electrum-cash` is easy, but tracking when the transaction gets confirmed involves tracking different related data which can cause problems if you naively unsubscribe while having multiple active subscriptions.
I have reached out to the backend developers to try and coordinate an update of the protocol to provide `blockchain.transaction.subscribe`, a subscription call that sends notifications when the status of a transaction changes which would simplify this process.
*Issues requesting the new feature:*
Electrs: https://github.com/BitcoinUnlimited/ElectrsCash/issues/86
Fulcrum: https://github.com/cculianu/Fulcrum/issues/32
electrum-cash: working with balances
Introduction
Electrum-cash is a javascript/typescript library for communicating with electrum servers. https://www.npmjs.com/package/electrum-cash/library
This example demonstrates how to get the balance of an address and how to get notified of changes to the balance of an address, using `v1.4.3` of the electrum protocol.
*To keep the example simple and clear, the code to set up and close a connection is omitted.*
Fetch current balance
To get the current balance for an address, send a `blockchain.address.get_balance` **request** to the server with the **address** as the first parameter.
// The address we want to get balance for.
const address = 'qr4aadjrpu73d2wxwkxkcrt6gqxgu6a7usxfm96fst';
// Request the balance from the server.
const balance = await electrum.request('blockchain.address.get_balance', address);
// Print out the current balance, in satoshis.
console.log(`Balance for '${address}' is ${balance.confirmed} satoshis confirmed, and ${balance.unconfirmed} satoshis unconfirmed.`);
*Example output for an existing wallet with a balance:*
Balance for 'qr4aadjrpu73d2wxwkxkcrt6gqxgu6a7usxfm96fst' is 1165925 satoshis confirmed, and 0 satoshis unconfirmed.
Subscribe to balance changes
To subscribe to balance update notifications, send a `blockchain.address.subscribe` **subscription** to the server with the **address** as the first parameter, then request the updated balance any time the status of the address changes.
// The address we want to get balance updates for.
const address = 'qr4aadjrpu73d2wxwkxkcrt6gqxgu6a7usxfm96fst';
// Create a callback handler for balance updates.
const balanceUpdateHandler = async function(adress)
{
// Request the balance from the server.
const balance = await electrum.request('blockchain.address.get_balance', address);
// Print out the updated balance, in satoshis.
console.log(`Balance for '${address}' is ${balance.confirmed} satoshis confirmed, and ${balance.unconfirmed} satoshis unconfirmed.`);
}
// Subscribe to update notifications to the address status from the server.
const balance = await electrum.subscribe(balanceUpdateHandler.bind(this, address), 'blockchain.address.subscribe', address);
*Example output when sending out all funds in the wallet:*
Balance for 'qr4aadjrpu73d2wxwkxkcrt6gqxgu6a7usxfm96fst' is 1165925 satoshis confirmed, and 0 satoshis unconfirmed.
Balance for 'qr4aadjrpu73d2wxwkxkcrt6gqxgu6a7usxfm96fst' is 1165925 satoshis confirmed, and -1165925 satoshis unconfirmed.
Balance for 'qr4aadjrpu73d2wxwkxkcrt6gqxgu6a7usxfm96fst' is 0 satoshis confirmed, and 0 satoshis unconfirmed.
With the typescript conversion of the electrum-cash library complete and relased, next up is automatic reconnection (and restoring subscriptions on reconnection) as well as websocket support, so that the library can be used in browsers.
Release v1.1.0 of electrum-cash.
This is a stability and quality improvement release with no new features, but it does convert the codebase to typescript and applies stronger linting.
Also fixes a handful of small bugs and edgecases:
- Trying to connect to an already established peer no longer returns undefined.
- Clusters can no longer select inactive peers to send data to.
- Clusters now validate connections before marking them as usable.
- Subscribing to the same electrum method multiple times no longer produce multiple event listener.
- Batch responses no longer breaks due to incorrect JSON.encode call.
CashAccounts Report: may2020
Yesterday, I was contacted by a user on discord who was having problems with the Bitcoin.com REST API they were using, and later a developer of a wallet having similar problems. The wallet developer was using a feature of the Bitcoin.com REST API that was not available under the api.cashaccount.info API.
I asked them to file a bug report on gitlab and this morning I pushed out an update to the indexing server that provides the missing functionality and they are now looking into changing what backend they use for their data.
*This reminded me that it has been quite a while since the launch of CashAccounts, and so I decided to take a look at some statistics..*
[sponsors]
Disclaimer: Not all data is good data.
At first, I just started collecting number and sharing on our discord server, but for this article I wanted to make sure that the data was at least reasonable, so I've decided to exclude the following from the data set as I feel that it severaly skews the statistics in an unreasonable way:
bitcoincash: qrdk...3erp (**creating one account per block** to gather statistics).
bitcoincash:qqrr...xy5p (**testing** and vast majority of names are **ytest)**.
bitcoincash:qzvm...w4qs (**testing** and vast majority of names ate **testXX)**.
bitcoincash:qztp...dxe2 (**programmatically created** and likely test/spam).
bitcoincash:qqrw...2ghc (**strong outliers** with systematic name **luckyXX** or **forumXX)**.
bitcoincash:qpeu...d2ds (**strong outliers** with systematic name **pancakeXX)**.
bitcoincash:qqy9...tgx2 (**strong outliers** with systematic name **ectest)**.
bitcoincash:qz3x...6x7c (**strong outliers** with systematic name **testse)**.
*This list is not exhaustive and I know that there's still a some amount of test/experiment related data include, but I believe we get rid of ~90% of the non-user data this way.*
Current usage and how we got here.
accounts unique_names unique_payloads
---------- ------------ ---------------
7882 5241 6741
Currently, we have almost 8,000 accounts using a bit over 5,000 unique accounts names and almost 7,000 unique payment information. This means that there is a significant overlap of names and that some users have more than one name for the same payment information. What we can't know though, is how many actual users there are, or how many accounts they each have on average.
week after release unique_names unique payloads
------------------ ------------ ---------------
1 1064 1092
2 171 148
3 45 52
4 21 21
5 247 228
6 53 45
7 43 42
8 18 17
9 10 11
10 5 5
Looking at the first 10 weeks are release, we can clearly see that there was a lot of early activity but that it tapered off over time, from having more than 1,000 accounts in the first week, to settling down in the tens of accounts per week at the end.
week after release unique_names unique payloads
------------------ ------------ ---------------
11 16 8
12 11 11
13 141 131
14 73 70
15 86 84
16 129 140
17 130 111
18 55 58
19 167 175
20 80 81
Numbers did pick up in the following 10 weeks, but then settled in and stayed at around 50 registrations per week for the coming 40 weeks:
week after release unique_names unique payloads
------------------ ------------ ---------------
21 48 54
22 60 62
23 37 32
24 34 37
25 25 25
26 44 45
27 42 44
28 37 43
29 87 106
30 50 45
31 54 53
32 23 31
33 29 33
34 10 15
35 42 49
36 54 61
37 40 48
38 46 52
39 25 23
40 34 37
41 22 24
42 31 29
43 28 34
44 51 59
45 38 44
46 23 27
47 38 45
48 41 46
49 27 35
50 30 36
51 63 75
52 51 67
53 52 63
54 37 44
55 72 83
56 54 57
57 58 70
58 43 43
59 68 74
60 64 73
After 60 weeks since release however, with more wallets opting to automatically create cashaccounts for their users, the number have increased significantly:
week after release unique_names unique payloads
------------------ ------------ ---------------
61 64 80
62 80 124
63 49 76
64 97 113
65 577 593
66 438 500
67 94 147
68 97 177
69 187 323
70 83 134
71 98 148
*This shows something that most of us knew from the start, that success of any naming system is going to come down to wallet support, and specifically strong wallet integration.*
How has the user experience panned out?
One of the concerns of the CashAccount protocol is that multiple users registering their names at the same time will get longer and longer account identifiers and the value of the system would gradually erode.
Now that we have well over a year worth of data, we can take a look to see how common this is, and how strong of an impact it has had.
accounts percent account_collision_count unique_names unique_payloads
---------- ---------- ----------------------- ------------ ---------------
354 4.5 2 186 222
77 1.0 3 27 44
37 0.5 4 9 28
35 0.4 5 8 10
6 0.1 6 1 1
10 0.1 10 2 4
18 0.2 17 2 17
With a total of around **6.5%** of registered accounts having had collisions, it is clear that this is more common than originally anticipated. With such a large number of accounts experiencing degraded quality, it makes sense to quantify how strongly affected they were, which can be seen here:
accounts percent account_collision_length unique_names unique_payloads
---------- ---------- ------------------------ ------------ ---------------
462 5.9 1 204 277
64 0.8 2 24 43
9 0.1 3 5 7
2 0.0 4 1 1
about **5.9%** of the accounts need to use a single extra number in order to ensure uniqueness and **0.8%** need to use two digits extra. There are a few cases that need to use 3 or 4 digits, but on they seem to be either strong outliers, or testing accounts:
account_collision_length name_list
------------------------ -------------------------------
3 Jordan,a,test,vikram,toytekin01
4 aap
Based on manual inspection of a bunch of randomly selected cases though, I would say that a large portion of the accounts that have collisions are the result of testing and experimentation and this is consistent with the fact that there has been virtually no user complaints or user support the last year.
There is still room for errors
There has been some failed registrations on the blockchain where the party trying to register an account has properly indicated that they want to register a CashAccount by using the CashAccount protocol identifier, but have then failed to follow the specification.
errors error_description
---------- ----------------------
6 Invalid account name
55 Missing payload data
5 Invalid payload length
*Based on my communication with wallets working on implementations, I believe practically all of these errors come from the initial development processes and should not be seen as users failing to understand the protocol.*
Where do we go from here?
After well over a year of usage I haven't found any significant problem with the CashAccount protocol and I still believe that user experience and user interface is one of the hard problems to overcome in order to gain mainsteam adoption.
To move forward and get CashAccounts more widely used and supported I believe that we need to start asking for it from the wallets we use. When people ask us where they should send us money, tell them your CashAccount identifier as well as your address.
We also need to lower the barriers that wallet developers have and make it easier for them to implement support for it. BitBox with the Bitcoin.com rest API worked great for a while, but what we really need is stronger integration into the infrastructure itself, like BUIP118. https://bitco.in/forum/threads/buip118-passed-implement-cashaccount-lookup-features.23749/
*Want to get involved? reach out to me on* *discord**,* *twitter* *or just write a comment below.* https://discord.gg/9kACN9t https://twitter.com/monsterbitar
Flipstarter Centralization Rant.
A viewpoint that recently cought my attention with regards to Flipstarter is that it allegedly represents a centralization concern, and that should the IFP fail to activate we would, going forward, expect to be dependent on a small set of big donors like Marc De Mesel and the SLP foundation.
I would like to formally address this viewpoint by stating that Flipstarter is not, and will not be, the sole mechanic for funding infrastructure development, and that Flipstarter serves a real need that has not been addressed with the IFP.
Let me back up a bit, and remind everyone that the IFP is a proposal to enforce via threat of orphaning otherwise valid blocks if they do not send a specific amount of the coinbase reward to any of the whitelisted parties. Variations of it has been discussed for years, miners have requested it on multiple occasions and as of late, Bitcoin ABC has listened to those miners and implemented it in their node software.
This implementation however, has been the topic of significant controversy and while I won't go into all the details, I would like to focus on one specific property of the implementation in more depth: The whitelist of candidate recipients.
[sponsors]
Why a whitelist?
As it turns out, the initial proposal was going to go through a centralized party and would disburse funds to projects. This was met with backlash and in order to allow miners to directly send funds to the projects they care about, a whitelist was suggested. This is an improvement to the previous iteration but someone has to determine the scope and choose what entity gets whitelisted, and what entity does not.
Instead of discussing the topic for a handful of years more, Bitcoin ABC instead took action and implemented a whitelist according to some self-selected criteria and released an update to their node software.
The content of this whitelist is what I will be focusing on in relation to the centralization concern.
Is flipstarter any better?
Currently, two out of the five flipstarter campaigns have fullfilled and the BCHN and Verde campaigns now have the funding they requested in order to complete the commitment they took in their campaign proposals.
While they are neither technically nor morally bound to their donors in any way, they undoubtedly are grateful and thankful for the donations and should they need to run further campaigns later on are more likely than before to want to cater to the known sources of donations. That is one of the drawbacks of having known donors, and a drawback they will now have to deal with.
**But what was the alternative?** After all, **neither** BCHN nor Verde was whitelisted in the IFP implementation by Bitcoin ABC, and there was no guarantees or even expectations for them to be funded by it.
Even if they were, wouldn't they have had the same relation to the miners who would have chosen to fund them through the IFP?
Consider for a moment that the miners could've funded both BCHN and Verde through the IFP, and that they would do so without disclosing their identities, this would still mean that the funded node developers would cater to the "miner need" - an important aspect of the Bitcoin Cash ecosystem, for sure - but would necessarily be better than catering to businesses, the token ecosystem or the speculators? Maybe. Maybe not.
So.. everything's bad?
No, everything's **connected**. When we talk about decentralization, we should be aware of the weakest link, as that is the limiting factor for decentralization.
If our only source of funding for the ecosystem is Flipstarter, then we're in a really bad position. If it's only through the IFP, we're also in a bad position. If it's only through a blockstream-style corporation, same thing.
Thankfully, that's not where we are today, and the centralization concerns are unfounded.
Bitcoin ABC has already raised 6000+ BCH, Bitcoin Unlimited still have plenty of funding as a result of previous fundraising, price appreciations and reasonable management of their funds. Bitcoin Cash Node now has 1000+ BCH from their Flipstarter and general donations, Bitcoin Verde has 240+ BCH from their Flipstarter and established working business relations.
*We should be embracing this diversity, as that is what makes us resilient.*
Flipstarter - A unique opportunity
The Flipstarter infrastructure campaigns are ready and with this article I would like to give my views as to why I think this is a unique opportunity for growth and profit. https://read.cash/@flipstarter/flipstarter-node-campaigns-will-be-live-on-fri-17-apr-2020-at-120000-am-utc-ab2c3136
Normally when you're speculating on the value of an asset, you commit at some price and then wait for the price to move in a favourable direction. You would do this because you believe you have better judgement, information or tools at your disposal that gives you an advantage.
The Flipstarter infrastructure campaigns, however, offer a different opportunity for speculators: a chance to **impact the outcome**, at a very **low cost**, and with **almost no risk**.
[sponsors]
"How does this work?", you ask.
The background for this unique opportunity is that Flipstarter is run as an assurance contract which means that when you pledge some funds to a campaign, those funds will **only** be sent to the recipient **if the campaign as a whole** fullfills. This means that you can pledge a relatively small amount of a campaign that you feel is likely to create a favourable outcome for you, and you will lose absolutely **nothing** if the campaign does not fullfill - and you stand to gain the benefits of a fullfilled campaign at a **very low cost** should it fullfill.
*You essentially enter a situation that has only positive outcomes.*
**Consider this:** If you have 1,000 BCH that are worth $333 each, and an opportunity presents itself that could empower the Bitcoin Cash ecosystem significantly and all you need to do is pledge 1 BCH to it, and get a thousand BCH's worth of empowerment, should you do it?
That is essentially what the Flipstarter infrastructure campaigns are offering: a way for those speculatively invested to put forward only a fraction of their asset in order to collectively improve the outlook for the asset class as a whole.
It is not everyday you can take **almost no risk** to pledge **just a fraction of your assets** in order to **impact the valuation** of the remaining coins you hold.
Javascript Electrum Library
In the last couple of months I've been working on a decentralized finance product for an upcoming company building Bitcoin Cash applications. Reliability is very important for us but I've been having some issues with the public and free bitcoin.com rest API.
Initially my thought was to replicate the backend and run it in-house, but it was relatively difficult to set up and manage, which led me to look for alternatives. I wanted something simple and reliable, with as few dependencies and set up costs as possible, with existing libraries available on NPM so I could integrate easily with the rest of my stack.
Knowing that the Electron Cash wallet has been around for a long time and seeing that Bitcoin Unlimited is building out an Electrum backend to use with their node software, I decided to look for libraries on NPM. There was more than a handful and many of them advertised that they were entirely free from dependencies. https://github.com/dagurval/ElectrsCash
But... nothing really worked for me.
I tried a bunch of libraries but due to various issues nothing really seemed to work. The NPM statistics showing just a handful of downloads per week for most libraries, the code quality being consistently low rated and most of them being old and unmaintained speaks for itself.
The feature set is also wildly broad with a lot of overlap with most libraries supporting most functionality, but none really supporting all, like encrypted connections, persistent connections, notification subscription, versioning support and so on.
Well, how hard can it be? Lets just build my own!
The protocol seemed fairly well documented and even though none of the existing libraries fit my needs I had plenty of code to learn from and reference, so I got started.
It took me a while, but now I have a library thats easy to use, encrypted by default, and has clean and easy to read code. Let's go over some examples and showcase how it works.
[sponsors]
How to get started
The library is open source and published to NPM under the `electrum-cash` name, so you can install it like you would any other NPM library:
npm install electrum-cash
You can read the source code and technical documentation on gitlab. https://gitlab.com/GeneralProtocols/electrum-cash/library https://generalprotocols.gitlab.io/electrum-cash/library/ElectrumClient.html
Standalone client
The simplest setup is to connect to a single server of your choice. While this looks very basic, under the hood you are actually getting a persistent, encrypted network connection with automatic keep-alive messages and built-in version negotiation and enforcement.
// Load the electrum library.
const ElectrumClient = require('electrum-cash').Client;
// Wrap the application in an async function to allow use of await/async.
const main = async function()
{
// Initialize an electrum client.
const electrum = new ElectrumClient('MyApplication', '1.4.1', 'bch.imaginary.cash');
// Wait for the client to connect.
await electrum.connect();
// Declare an example transaction ID.
const transactionID = '4db095f34d632a4daf942142c291f1f2abb5ba2e1ccac919d85bdc2f671fb251';
// Request the full transaction hex for the transaction ID.
const transactionHex = await electrum.request('blockchain.transaction.get', transactionID);
// Print out the transaction hex.
console.log(transactionHex);
// Close the connection.
await electrum.disconnect();
};
// Run the application.
main();
Multiple clients (Clusters)
For professional use, having a single point of failure is not an acceptable outcome. Integrating network reliability directly in an application lets you build the best user interface but has a higher development cost and is prone to difficult errors such as race conditions.
By building these features into the library instead, you get to spend more time building on your application, and less time fighting network based backend problems.
From a usage perspective there is very little change, just change from using a `Client` to using a `Cluster` and provide some basic setup configuration.
Failover
With a cluster, you can add more than one server and if a server goes down the library will automatically mark the server as unavailable and send your requests to different servers on your server list.
When the server becomes available again, it is automatically re-enabled.
Low latency
If your application requires consistent short response times, adding multiple servers and requesting data from them in parallel, then using the first available response allows you to run your application with the latency of the fastest server at all times.
High integrity
If you're not running your own servers, or your requirements are very stringent you can configure the cluster to cross-verify multiple server responses before handing them over to your application.
By doing so you ensure that no single server can provide you with fraudulent data, but the latency of the response will be longer as we need to wait for more servers to respond before giving the data to your application.
Blind privacy
Using a single server has the privacy benefit that you're only disclosing information to a single peer. For clusters you would instead use a large number of servers to spread your requests making it difficult for any single server to determine the context for your actions.
Bringing it together to build a reliable, performant setup
If you don't have any specific requirements and just want the backend to work and get out of your way, you can strike a balance between reliability and performance by getting all of the good stuff together.
Configure the cluster to have a decent integrity confidence with at least two servers having to be consistent, set it to poll a handful of servers and then add as many servers as you want to have for backup. The default strategy for selecting which servers to poll is random, so you automatically get some load-balancing as well.
// Load the electrum library.
const ElectrumCluster = require('electrum-cash').Cluster;
// Wrap the application in an async function to allow use of await/async.
const main = async function()
{
// Initialize an electrum cluster where 2 out of 3 needs to be consistent, polled randomly with fail-over.
const electrum = new ElectrumCluster('MyApplication', '1.4.1', 2, 3, ElectrumCluster.ORDER.RANDOM);
// Add some servers to the cluster.
electrum.addServer('bch.imaginary.cash');
electrum.addServer('electroncash.de');
electrum.addServer('electroncash.dk');
electrum.addServer('electron.jochen-hoenicke.de', 51002);
electrum.addServer('electrum.imaginary.cash');
// Wait for enough connections to be available.
await electrum.ready();
// Declare an example transaction ID.
const transactionID = '4db095f34d632a4daf942142c291f1f2abb5ba2e1ccac919d85bdc2f671fb251';
// Request the full transaction hex for the transaction ID.
const transactionHex = await electrum.request('blockchain.transaction.get', transactionID);
// Print out the transaction hex.
console.log(transactionHex);
// Close all connections.
await electrum.shutdown();
};
// Run the application.
main();
About reference.cash
In early 2019 I proposed that we should build an independent set of documentation for the Bitcoin Cash network. While it would take several months until the right talent would be found to initiate this work, in late 2019 at the Bitcoin Cash City conference, that talent was discovered.
After some months of work and some initial hurdles the website reference.cash has been put online and the content is available under a Creative Commons license.
[sponsors]
I had high hopes for the benefits that this documentation would bring but I was somewhat misguided on the amount of effort this task actually represents, and as such I did not set a budget of appropiate size.
I've since learned that this documentation is more important than I initially imagined since it represents in action, one of the underlying fundamental ideas of I see in Bitcoin Cash - that the network is open to anyone and that competition is welcome.
It is trivial to merely express that you are for an open competitive network and multiple node implmentations. It is much more difficult to act in a way that fosters and builds an ecosystem where that becomes a reality. Having an open, public, accurate and up-to-date specification for the network, the documentation if you will, is critical if you want developers to feel productive and confident. If you ask any programmer how they feel about using external libraries or systems that either have no documentation, or have mixed and incorrect documentation, you will get the same response:
it's not **fun**. it's not **good**. it's not **worth their time**.
I want the really good developers, that rare talent in the world, to look at our documentation and practices and feel empowered and eager to experiment. When you're building for a network based on consensus, your world is more black and white than most people would appreciate. If you don't have good documentation, chances are you will feel doubtful about your ability to participate in a way that matches consensus - after all, with poor documentation you'd have to go the trial-and-error path, which is long and ardous.
Sadly, the truth is that I am not the talent to build this documentation. If I could, I would've been on this from the get go with all my heart. For now, I will do the next best thing though: I will contribute where I can, and I will keep telling people that we should absolutely do our best to keep those who can write this documentation well supported in that endeavor.
The budget for BUIP121 - writing the formal specification - was misguided. There's work done, and there's talent ready to do more, so I have written two new proposals to Bitcoin Unlimited to extend this funding, and to extend the work to also include testing data, which can be used to form something of a validation suite that allows new actors to gain confidence in their ability to stay in consensus.
This article however, is not to encourage people to go vote on those BUIPs, instead the purpose here to help spread a bit of awareness of community aspect of the documentation and encourage people to take a look at https://reference.cash/ and hopefully contribute, even if it's minor changes.
I wish the best of all to all participants in this ecosystem, past, present and future, and hope that for 2020, more people will step up to contribute.
How I wish read.cash integrated CashID
Read.cash has supported badger-specific cashid for a while now. I'm glad there's an option to login that, in theory, doesn't need username, passwords and emails. Sadly, the design and implementation means you still need a username+password as well as email, just to get started.
[sponsors]
Here's a quick mockup of how I would like the login-flow to look instead - Just a simple login at the top right corner, and if you click the text you get to the regular login screen like any user would expect:
If you hover the cashid icon though, you'd get this pop-up:
Scan the QR code with your smartphone wallet and you're logged in and ready to rumble!
Note: if you try to login with a new account, then the site should just create the account on the spot, and show you a "new user" tutorial / guide and in that let you set your account profile name and similar.
Of course this mockup is crude and ugly, but I just wanted to showcase what I think a good authentication flow is:
1) Don't leave the content - **just authenticate**
2) Don't be wallet-specific, **follow the specification**
3) Don't use email - it's from the 90's and we have better alternatives now.
How to host a successful meetup.
It is easy to misstake strong attendance for success when talking about meetups, but while having people show up is an important factor it is **not the deciding factor**. Meetups as small as only 2~3 people can still be considered successful - depending on what the goal of the meetup is.
This article will assume that the goal of a meetup is to **increase user and merchant adoption** and to practically **demonstrate the usecase of peer to peer electronic cash**.
My view is that all people are different and I believe that we will need different types of meetups to reach the broadest audience possible. Every new user is valuable and even if a meetup does not succed at introducing a newcomer to the ecosystem - maintaining a community is also very important as it is the foundation on which new adoption builds.
[sponsors]
Here's three types of meetups that I think work well, and shows just how different meetups can be:
#1, the close social circle
One way to host a meetup is to simply bring friends and family together with the expectation of discussing the topics at hand, and announce that curious people are welcome to join if they so wish.
This type of meetup is usually relatively small and has very little maintainance.
**People:** Few - mostly close friends with the occasional visitors.
**Location:** Public or private - can be held at a café, someones workplace or at home.
**Topics:** Anything - the topics for discussion depends mostly on the core group.
**Activities:** Trusted - the activities usually assumes trust with the meetup attendees.
**Swag:** Rarely - there is no real need to hand out merchandise.
Imagine a group of 3~6 people who meet up at a café, usually talks about the parts of Bitcoin Cash that they have personal interests in and could get somewhat technical from time to time. When they get visitors they help out with the basics like setting up a wallet and making backups, but the discussion remains on the skill level of the core group most of the time.
*Sometimes they might mix things up and play a friendly game of cards or watch a crypto-related movie, and there is a general sense of trust and companionship.*
#2, the openly unconditional space
Another way to host a meetup is to focus not on the core group, but on the meetings between people and ideas. In this setup the meeting is in a public space and the topics for discussion varies wildly from one meeting to another depending on what people happen to be there.
The meetup is announced publically and attendence can be anything from a few to many.
**People:** Varying - usually the meeting host and mostly curious non-technical people.
**Location:** Public - meeting is in an accessible public space, often a café or pub.
**Topics:** Anything - often recent news limited to the attendees skill and backgrounds.
**Activities:** Trustless - any non-discussion activity is are best kept trustless.
**Swag:** Occasionaly - Having merchandise is great for the identity but not required.
Consider a meetup at central pub or bar, or maybe a restaurant, with plenty of room. Anyone can come and go as they please during the expected meetup time. There's multiple discussions going on between various groups of people and more often than not there's newcomers and curious visitors present.
Sometimes someone brings merchandise like stickers and tshirt, sometimes they bring new products to talk about and test out. When possible it's in a place that accept Bitcoin Cash for payment, and if such a place is not available they find creative ways to let newcomers experience payments on the spot anyway.
#3, the respectfully formal agenda
It is also possible to hold meetups that are more formal. With a known list of topics to talk about, projects or people to meet and products to market, this type of meetup comes with a bit more effort to set up and maintain, but also allows to bring in a different set of a people.
The main value proposition for formal meetups is the creation of new relations or marketing of skills or products.
**People:** Varying - An organizer, possibly speakers/representatives and enthusiasts.
**Location:** Public - Usually held at meeting room, conference hall or similar.
**Topics:** Known agenda - the topics and activities should be public before the meetup.
**Activities:** Varying - workshops, project and product presentations are common.
**Swag:** Common - merchandise helps build brand recognition and user relations.
The meetup is held in a public place but only for people who know they are invited. The attendees are more specialized, often people looking to work in the field, or representatives of companies who are interested in the field. While the meetup itself is usually free, it is not uncommon to see money being used on the meetup; be it for speculative trading, selling related products and services or engaging in business relations.
This type of meetup is a great place to introduce merchants and companies to crypto and help them get engaged in the community.
How to get started.
If you've read this and want to get started and host a meetup, but think this is still too vague, then feel free to reach out to me and I will help you get in contact with others who have experience with this and together we will sort out the practicalities.
If you've read this and are not sure but still would like to know more, let me know and I'll consider to make follow-up articles with more a more practical perspective for each type of meeting, with tips and tricks and other things I've learnt over the years.
If you have different expectations on how a meeting should be, feel free to share your ideas in the comments.
Why we should allow more than one OP_RETURN per transaction.
I will start off by saying that I am fully committed to the idea that we should prioritize the **cash** usecase and that by storing arbitrary data on chain we are reducing the ability for that usecase to scale.
That said, I believe that for us to be successful at cash we need to solve some outstanding usability problems and allow people to use cash in a way that suits them, rather than impose a fixed and strict way on everyone.
[sponsors]
What good will come from spamming the blockchain with data?
Having the ability to store multiple sets of small data attached to transactions allows us to enrich the cash usecase by adding metadata that has properties that is otherwise difficult to achieve.
For example, consider one of the technical limitations of Bitcoin Cash today, the fact that transactions do not have a clear sender. This is relatively simple to solve by just adding an OP_RETURN to the transaction containing the senders identity and a signature by the senders key to prove that identity. To retain the privacy, this information could be encrypted.
Now this isn't a good argument for multiple OP_RETURNs in itself, since it's doable without, but what if the value you are sending is an SLP token? In that case SLP has already taken up the currently allowed OP_RETURN space and the user experience is degraded.
This empowering of the cash usecase is something I would love to see happen sooner rather than later. While multiple OP_RETURNs could be used for things that are detrimental to the cash usecase ("spamming"), retaining the existing size limits per OP*_*RETURN and and being careful about how we expand this functionality should help keep the various use cases in a reasonable balance.
Actual usecases
During the initial discussions I've had about this, I have frequently been asked what the actual usecases are. My answer to this is that I personally have a use for this with my **CashIntents** protocol, but this is not about me or my needs.
Just as it's not always easy to see the real value in exciting new things, I believe that the ability for OP_RETURN protocols to interact in a symbotic and beneficial way, like the **SLP** and **CashIntent** combination I listed earlier, is the real value here.
Having just a little bit more room for innovation here could prove to be very valuable as new developers come along with innovative ideas.
This is already a problem today
The first example where this limitation is already a problem today I found when talking about an SLP DEX developer. Since SLP is taking up the OP_RETURN, currently they already shove data they need to track with the transactions inside the transaction, but are using/abusing a different storage place for it.
I'm not saying that just because someone (like me) have an issue and could benefit from a change in this limitation, we should just go ahead and do it. What I am saying is that there's innovation to be had here if we opened up a little, and that it's time to have a healthy discussion on the subject.
What can we do about this?
In the end, this is going to come down to changing the consensus rules. The first step towards doing so should be to have a healthy discussion about it and for the involved parties to be clear about what they want to do and what they can accept.
To this end, I've submitted two improvement proposals to Bitcoin Unlimited, one that is a relatively straight forward (simply allow more), and one that has a more restrictive ruleset that keeps the total size limitation intact. https://bitco.in/forum/threads/buip-multiple-op_return-with-less-rules.24947/ https://bitco.in/forum/threads/buip-multiple-op_return-with-shared-size-limit.24946/
What am I doing now?
Quite some time ago I was spending almost all of my time building things for Bitcoin Cash and it felt like I was making immense progress:
For CashID a specification, library and tools. https://gitlab.com/cashid/protocol-specification https://gitlab.com/cashid/libraries https://gitlab.com/cashid/identity-manager
For CashAccounts a specification, website, lookup service and wallet integrations. https://gitlab.com/cash-accounts/specification https://www.cashaccount.info https://gitlab.com/cash-accounts/lookup-server https://www.cashaccount.info/#wallets
For Cashual an actual working wallet that is userfriendly. https://play.google.com/store/apps/details?id=org.monsterbitar.wallet&hl=en_US
Some people might've started wondering why I haven't gotten any other projects out since then - after all it's been several months...
[sponsors]
I got a lot of things going on though
... even though I haven't managed to get things to production, I'm still around and working on BitcoinCash just as much as I used to, just a bit more spread out over many things and on a bit more complex products that takes longer to get to market.
I've also spent quite a bit of time on doing things that is good for the ecosystem overall, but that is not things I'm doing on my own or things that can be "shipped" or "published".
So what are these vague things?
I've submitted numerous BUIPs. (118, 119, 120, 121) https://bitco.in/forum/threads/buip118-passed-implement-cashaccount-lookup-features.23749/ https://bitco.in/forum/threads/buip119-passed-implement-sending-to-cashaccount.23750/ https://bitco.in/forum/threads/buip120-passed-replace-leveldb-with-an-immutable-stateless-storage-design.23734/ https://bitco.in/forum/threads/buip121-passed-create-formal-bch-specifications.23762/
I've done review and given feedback to a lot of different projects.
I've joined multiple working groups.
I've started a some new of projects (where2cash, CashIntents) https://gitlab.com/monsterbitar/where2.cash https://gitlab.com/monsterbitar/cash-intents
Talked with a lot of important people at the BitcoinCashCity conference. https://bitcoincashcity.com/
Alright, but that's too vague. What are you doing now?
Right now I'm spending most of my time building on a commercial smart contract project with a small team, but I cannot share any specifics about the product. Needless to say, I've taken a deep dive into the scripting language of BitcoinCash as a result of this.
It sucks that I can't **share more** on this. I wish I could just tell the world, but this product is being done in a professional capacity under a company that is still in the process of being founded. It's all very hush-hush until it's ready.
I'm also working on a somewhat of a replacement for bitbacker.io that will be tightly integrated in social media rather than be a stand-alone website.
What happened to all the other stuff?
There's a handful of projects that I was working on before, but that I've put aside for now and want to revisit later on. I can't promise when (or even if) I go back to these, but I **really** want to do so - I think these projects are too important to just give up:
**Cashual Wallet** - Needs to **change wallet library** and add **CashIntents** and **CashID**.
**Where2cash** - Needs an **add merchant view** and database of **local communities**.
That's it, folks!
It's been a great journey to come to be a part of this community and I hope I will be spending many years to come building on the **Peer-to-Peer Electronic Cash** that works and that by doing so I help people become more sovreign, independent and empowered.
Evaluation of read.cash
First Impression
The website homepage is clean and non-cluttered which is generally positive as it means that the majority of the space is reserved for content. I feel though, that a short introduction to the platform itself would be useful on the main page.
The footer of the page could do with some more improvements as well, for example contact information, links to social media accounts and similar is commonly found (and therefor looked for) in the footer area.
[sponsors]
The editor
The text editor for making new items is simple and works, but with very little explanations and no guide or tutorial many users will find it difficult to use. It doesn't seem to be able to do embedding of other content, like images, audio or video.
*On a sidenote, the editor offers headers by the name of H1, H2 and H3, which for the HTML-savvy users might feel really weird, given that they have known uses and H1 should already be set by the contents title.*
The wallet
The wallet offers the basic functionality. There are options to deposit and withdraw, it uses the common 12-word backup mechanic but it doesn't disclose the derivation path which means using it will be hit-n-miss depending on what wallet you want to import it to. There's significant warnings about beta quality and while I don't see anything in the frontend that justifies that warning - it's still a very good thing to have for a new product until it has matured and seen proper peer use.
Verdict
After a quick test and looking over how it works, my conclusion is that while this is a work-in-progress and there's likely going to be issues during the beta period, the overall experience is good.
For my personal use, the lack of image and video embeds, as well as the somewhat quirky out-of-the-way editor, means I will not be using this service yet. What would be desirable for me personally is markdown support - there's so far no editor out there that I've used that beats the user experience of markdown for those who already use markdown extensively elsewhere, like on discord, telegram or github/gitlab.