verb distribute ether or tokens to multiple addresses
The real beauty of Web 3.0 ecosystem we are building are open protocols. Anyone can tap into dharma loan protocol or 0x protocol exchange contract and get into shared liquidity pool for free. You can mix and match these too, creating completely unique products and markets.
A protocol for fungible tokens (ERC-20) is probably the most successful thus far. It secures about $13 billion across a thousand assets. This protocol is quite simple actually, it defines a
transfer function which updates balances in token contract and emits a
But what allows to tap into it is the concept of
allowance. A user can
approve another account to transfer some amount on her behalf. For example, an exchange calls
transferFrom user wallet when the order is filled. It’s programmed not to transfer more than the signed amount even though the allowance is set to
-1 (meaning infinity).
Like a good Unix tool, Disperse contract does a simple job and does it well, that’s why we shaved off every single bit to optimize for gas costs. A naive implementation of Disperse function might look like this:
disperseTokenSimple(token, recipients, values)
However, it’s not an optimal solution because the aforementioned
transferFrom updates allowance on each call in addition to balances. That’s an additional 5000 gas on each transfer.
A better way would be to calculate the total,
transferFrom it to the contract address and then distribute the tokens using
transfer function. There is no risk of funds being stuck because transactions work in “all or nothing” manner and the state will revert if anything goes wrong.
disperseToken(token, recipients, values)
The cost also depends heavily on whether each recipient has previously had any balance. Zero balance is the worst case because storing a new state entry costs 20,000 gas as opposed to 5000 gas for changing the value.
Gas costs as described in Ethereum yellow paper
Here are the benchmark results for this contract (outlined in red) compared to sending tokens to one recipient at a time (grey). One block can fit up to 218 token transfers, while Disperse transaction can fit 2.9x as much, up to 634 transfers.
Same goes for ether, one block can accommodate 380 regular transfers while Disperse can fit 2.18x more, up to 830 transfers. However, distributing ether to uninitialized accounts costs more because contracts pay 25,000 gas for calls that result in creation of new accounts as opposed to a flat 21,000 gas cost of a regular transfer.
If you are using Metamask, you are probably connected to Infura node. It limits the maximum transaction size to 32 KB. This anti-spam measure caps the amount of recipients you can specify. You can broadcast a larger transaction by connecting to to a local node like Geth or Parity Ethereum. Infura’s limit is shown with a dotted line on the charts.
We believe this space needs more builders and less fraud. Therefore Disperse doesn’t incorporate any useless token, has no sale and takes no fees.
It’s a useful dapp that’s available day one on nine networks:
- Ethereum and its testnets Ropsten, Kovan, Rinkeby;
- POA Network and its testnet Sokol;
- xDAI Chain;
- Ethereum Classic;
Go try it out on disperse.app.
Read the research paper.
Let us know what you think on Telegram.
- Benchmark results have been revised accounting for a transaction size limit of 32 KB on Infura which is the default RPC provider on Metamask. Example transactions have been added.