Browse Source

Calculate total PoW energy usage in watts (#31)

pull/32/head
Luke Childs 3 years ago
committed by GitHub
parent
commit
135af8d912
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 90
      README.md
  2. 73
      api/algorithms.js
  3. 42
      api/data.js
  4. 11
      js/format-hashrate.js
  5. 12
      js/format-units.js
  6. 6
      js/index.js
  7. BIN
      screenshot.png
  8. 4
      style.css

90
README.md

@ -13,83 +13,78 @@ Compare the time required for an equivalent amount of work to be completed betwe
## How are these values calculated?
It's easy to compare blockchain hashrates when the Proof-of-Work algorithm is the same. For example if Bitcoin has a hashrate of SHA-256 @ 40 PH/s and Bitcoin Cash has a hashrate of SHA-256 @ 2 PH/s, it's easy to see that for a given period of time the Bitcoin blockchain will have 20x (40/2) the amount of work securing it than the Bitcoin Cash blockchain. Or to say that differently, you need to wait for 20x more Bitcoin Cash confirmations before an equivalent amount of work has been done compared to the Bitcoin blockchain. So 6 Bitcoin confirmations would be roughly equivalent to 120 Bitcoin Cash confirmations in the amount of work done.
It's easy to compare blockchain hashrates when the Proof-of-Work algorithm is the same. For example if Bitcoin has a hashrate of SHA-256 @ 150,000 PH/s and Bitcoin Cash has a hashrate of SHA-256 @ 3,000 PH/s, it's easy to see that for a given period of time the Bitcoin blockchain will have 50x (150,000/3,000) the amount of work securing it than the Bitcoin Cash blockchain. Or to say that differently, you need to wait for 50x more Bitcoin Cash confirmations before an equivalent amount of work has been done compared to the Bitcoin blockchain. So 6 Bitcoin confirmations would be roughly equivalent to 300 Bitcoin Cash confirmations in terms of the amount of work done.
However if the Proof-of-Work algorithms are different, how can we compare the hashrate? If we're comparing Bitcoin (SHA-256 @ 40 PH/s) against Litecoin (Scrypt @ 300 TH/s), the hashes aren't equal, one round of SHA-256 is not equivalent to one round of Scrypt.
However if the Proof-of-Work algorithms are different, how can we compare the hashrate? If we're comparing Bitcoin (SHA-256 @ 150,000 PH/s) against Litecoin (Scrypt @ 350 TH/s), the hashes aren't equal, one round of SHA-256 is not equivalent to one round of Scrypt.
What we really want to know is how much energy is being consumed to provide the current hash rate. Literal energy, as in joules or kilowatt hours. It would be great if we had a universal metric across blockchains like kWh/s to measure immutability.
What we really want to know is how much power is being consumed on each chain to provide the current hash rate. Literal power, as in watts. So how can we calculate that?
However that's fairly hard to calculate, we need to know the average power consumption of the average device used to mine. For GPU/CPU mined Proof-of-Work algorithms this varies greatly. For ASIC mined Proof-of-Work algorithms it varies less, however it's likely that ASIC manufacturers are mining with next generation hardware long before the public is made aware of them, which we can't account for.
Well it's actually pretty simple.
There's no automated way to get this data and no reliable data source to scrape it from. We'd need to manually research all mining hardware and collate the data ourself. And as soon as newer mining hardware comes out our results will be outdated.
- Find the most advanced publically available hardware for a chains PoW algorithm.
- Calculate the devices hashing efficiency in joules per hash (j/h).
- Multiply the chain's hashrate by it's PoW algorithms j/h value.
- Now we have the total watts consumed by the blockchain.
Is there a simpler way to get an estimated amount of work per blockchain in a single metric we can use for comparisons?
> **Note:** This makes the assumption that every single miner for the blockchain is using the most advanced hardware, which isn't true, but it's close enough.
Yeah, there is, we can use NiceHash prices to estimate the cost in $ to secure a blockchain for a given timeframe. This is directly comparable across blockchains and should be directly proportionate to kWh/s, because after all, the energy needs to be paid for in $.
The power consumption in watts can then be used as a reliable metric to compare Proof-of-Work between chains.
How can we estimate this?
As an example:
- Get the blockchains Proof-of-Work algorithm
- Lookup the average price per hash on NiceHash for this algorithm
- Multiply price per hash by total hashrate per second
**Bitcoin**
Now we have an estimated total Proof-of-Work metric measured in dollars per second ($/s).
- Algo: SHA-256
- Hashrate: 150,000 PH/s
- Best Miner: Antminer S19 Pro (110 TH/s @ 3250 W)
- Joules per hash: 3250 W / 110 TH/s = 0.000000000029545 J
- Watts: 150,000 PH/s * 0.000000000029545 J = 4.43 GW
The $/s metric may not be that accurate. Miners will mark up the cost when reselling on NiceHash and we're making the assumption that NiceHash supply is infinite. You can't actually rent 100% of Bitcoin's hashpower from NiceHash, there isn't enough supply.
**Litecoin**
However that's not really an issue for this metric, we aren't trying to calculate the theoretical cost to rent an *additional* 100% of the hashrate, we're trying to get a figure that allows us to compare the cost of the *current* total hashrate accross blockchains. Even if the exact $ value we end up with is not that accurate, it should still be proportionate to kWh/s. This means it's still an accurate metric to compare the difference in work done over a given amount of time between blockchains.
- Algo: Scrypt
- Hashrate: 350 TH/s
- Best Miner: Innosilicon A6+ LTCMaster (2.2Gh/s @ 2100 W)
- Joules per hash: 2100 W / 2.2Gh/s = 0.000000954545455 J
- Watts: 350 TH/s * 0.000000954545455 J = 334 MW
So how do we compare these values between blockchains?
So we can deduce from those calculations, if the entire Bitcoin hashrate was mined by Antminer S19 Pros it would require 4.5 GW of power, and if the entire Litecoin hashrate was mined by Innosilicon A6+s it would require 330 MW of power.
Once we've done the above calculations and got a $/s cost for each blockchain, we just need to factor in the average block time and calculate the total $ cost for a given number of confirmations. Then see how much time is required on the other blockchain at it's $/s value to equal the total cost.
Therefore Litecoin's hashrate is around 7% (330/4500) the power of Bitcoin's, it takes around 14x longer for the Litecoin blockchain to do the same amount of work.
Once we've done the above calculations and got power consumption in watts for each blockchain, we can calculate the equivalent amount of confirmations across chains by factoring in the average block time and calculating the energy required for a given number of blocks. Then we check how many blocks are required on the other blockchain at it's power consumption to expend an equivalent amount of energy.
So to calculate how many Litecoin confirmations are equivalent to 6 Bitcoin confirmations we would do:
- Bitcoin (SHA-256 @ 40 PH/s) or ($100/s)
- Litecoin (Scrypt @ 300 TH/s) or ($10/s)
- Bitcoin (SHA-256 @ 150,000,338 PH/s = 4.43 GW)
- Litecoin (Scrypt @ 350 TH/s = 334 MW)
- Bitcoin's average block time is 10 minutes (600 seconds)
- 6 Bitcoin confirmations on average is 60 minutes (3,600 seconds)
- Bitcoin's total $ cost for 6 confirmations is ($100 * 3,600 seconds) $360,000
- At Litecoin's hashrate of $10/s it would take ($360,000 / $10) 36,000 seconds (10 hours) to complete an equivalent amount of work
- Bitcoin's total energy required for 6 confirmations is (4.43 GW * 3,600 seconds) 15.94 terajoules
- At Litecoin's power consumption of 330 MW it would take (15.94 terajoules / 334 MW) 47,724 seconds (13 hours) to complete an equivalent amount of work
- Litecoin's average block time is 2.5 minutes (150 seconds)
- The amount of Litecoin blocks expected over this period of time is (36,000 seconds / 150 seconds) 240 blocks.
- The amount of Litecoin blocks expected over this period of time is (47,724 seconds / 150 seconds) 318 blocks.
Therefore we can say that 240 Litecoin confirmations are roughly equal to 6 Bitcoin confirmations in total amount of work done.
Therefore we can say that 318 Litecoin confirmations are roughly equal to 6 Bitcoin confirmations in total amount of work done.
### Notes
#### $/s doesn't mean what it sounds like it means.
The $/s values should not be taken as literal costs.
For example:
> - Bitcoin's total $ cost for 6 confirmations is ($100 * 3,600 seconds) $360,000
This is does not mean you could do a 51% attack on Bitcoin and roll back 6 blocks for a cost of $360,000. An attack like that would be much more expensive.
The $/s value is a metric to compare the amount of work at the current hashrate between blockchains. It is not the same as the cost to add hashrate to the network.
When adding hashrate to a network the cost will not scale linearly with hashrate. It will jump suddenly at certain intervals.
For example, once you've used up the available hashrate on NiceHash you need to add the costs of purchasing ASICs, then once you've bought all the ASICs in the world, you'd need to add the costs of fabricating your own chips to keep increasing hashrate.
#### These metrics are measuring "work done", not security.
More "work done" doesn't necessarily mean "more security".
For example take the following two blockchains:
- Bitcoin Cash (SHA-256 @ 2 PH/s) or ($5/s)
- Zcash (Equihash @ 4 GH/s) or ($3/s)
- Bitcoin Cash (SHA-256 @ 3,000 PH/s = 90 MW)
- Zcash (Equihash @ 6 GH/s = 20 MW)
Bitcoin Cash has a higher $/s value than Zcash so we can deduce it has more "work done" over a given timeframe than Zcash. More kWh/s are required to secure it's blockchain. However does that really mean it's safer?
Bitcoin Cash has higher power consumption than Zcash so we can deduce it has more "work done" over a given timeframe than Zcash. However does that really mean it's more secure?
Zcash is the dominant blockchain for it's Proof-of-Work algorithm (Equihash). Whereas Bitcoin Cash isn't, it uses the same algorithm as Bitcoin. In fact just 5% of Bitcoin's hashrate is equivalent to all of Bitcoin Cash's hashrate.
Zcash is the dominant blockchain for it's Proof-of-Work algorithm (Equihash). Whereas Bitcoin Cash isn't, it uses the same algorithm as Bitcoin. In fact just 2% of Bitcoin's hashrate is equivalent to all of Bitcoin Cash's hashrate.
This means the cost of a 51% attack against Bitcoin Cash could actually be much lower than a 51% attack against Zcash, even though you need to aquire more kWh/s of work, the cost to aquire those kWh/s will likely be lower.
This means the cost of a 51% attack against Bitcoin Cash could actually be much lower than a 51% attack against Zcash, even though you need to aquire more MW of hashpower, the cost to aquire that hashpower will likely be lower.
To attack Bitcoin Cash you don't need to acquire any hardware, you just need to convince 5% of the Bitcoin hashrate to lend their SHA-256 hashpower to you.
To attack Bitcoin Cash you don't need to acquire any hardware, you just need to convince 2% of the Bitcoin hashrate to lend their SHA-256 hashpower to you.
To attack Zcash, you would likely need to fabricate your own Equihash ASICs, as almost all the Equihash mining hardware in the world is already securing Zcash.
@ -105,16 +100,13 @@ You should factor in:
- What is the market cap of this cryptocurrency?
- What is the daily trading volume of this cryptocurrency?
- What is the $ value of this transaction?
- What is the probability of a successful double-spend, given the attacker's hashrate?
If the cryptocurrency doesn't dominate the Proof-of-Work it can be attacked more cheaply.
If the cryptocurrency isn't the dominant cryptocurrency for it's Proof-of-Work algorithm it can be attacked much more cheaply.
If the market cap or trading volume is really low, an attacker may crash the price of the currency before they can successfully double spend it and make a profit. Although that's more relevant in the context of exchanges rather than individuals accepting payments.
If the value of the transaction is low enough, it may cost more to double spend than an attacker would profit from the double spend.
If the attacker can't muster a high enough percentage of the network hashrate, a double-spend attempt can fail, increasing the average cost of a successful attack. The probability depends on the number of confirmations and the effective hashrate of the attacker, but not on the time between blocks, giving an advantage to networks with faster blocks. This is discussed [here](https://arxiv.org/pdf/1402.2009.pdf).
Ultimately, once the cost of a double spend becomes higher than an attacker can expect to profit from the double spend, that is when a payment can probably be considered "finalised".
## Something wrong?
@ -123,7 +115,7 @@ Do you think I've made a mistake or got something wrong? Please [open an issue](
## Credit
Data is sourced from [whattomine.com](https://whattomine.com/) and [nicehash.com](https://www.nicehash.com/).
Cryptocurrency data is pulled from [whattomine.com](https://whattomine.com/).
## License

73
api/algorithms.js

@ -0,0 +1,73 @@
const sendJson = require('./util/send-json');
const ANTMINER_S19_PRO_WATTAGE = 3250;
const RTX_3090_WATTAGE = 285;
const INNOSILICON_A6_PLUS_WATTAGE = 2100;
const AMD_THREADRIPPER_1920X_WATTAGE = 180;
const STU_U6_WATTAGE = 2200;
const ANTMINER_Z15_WATTAGE = 1510;
const STU_U1_PLUSPLUS_WATTAGE = 2200;
const GOLDSHELL_CK5_WATTAGE = 2400;
const rawHashes = (hashes, unit) => {
const multiplier = {
H: 1000 ** 0,
KH: 1000 ** 1,
MH: 1000 ** 2,
GH: 1000 ** 3,
TH: 1000 ** 4,
PH: 1000 ** 5
};
return hashes * multiplier[unit];
};
const getAlgorithms = () => [
{ // https://www.asicminervalue.com/miners/bitmain/antminer-s19-pro-110th
name: 'SHA-256',
joulesPerHash: ANTMINER_S19_PRO_WATTAGE / rawHashes(110, 'TH')
},
{ // https://www.nicehash.com/profitability-calculator/nvidia-rtx-3090
name: 'Ethash',
joulesPerHash: RTX_3090_WATTAGE / rawHashes(120, 'MH')
},
{ // https://www.asicminervalue.com/miners/innosilicon/a6-ltcmaster-1
name: 'Scrypt',
joulesPerHash: INNOSILICON_A6_PLUS_WATTAGE / rawHashes(2.2, 'GH')
},
{ // https://www.nicehash.com/profitability-calculator/amd-cpu-threadripper-1920x
name: 'RandomX',
joulesPerHash: AMD_THREADRIPPER_1920X_WATTAGE / rawHashes(7.24, 'KH')
},
{ // https://minerstat.com/hardware/nvidia-rtx-3090
name: 'Etchash',
joulesPerHash: RTX_3090_WATTAGE / rawHashes(121.16, 'MH')
},
{ // https://www.asicminervalue.com/miners/strongu/stu-u6
name: 'X11',
joulesPerHash: STU_U6_WATTAGE / rawHashes(440, 'GH')
},
{ // https://www.asicminervalue.com/miners/bitmain/antminer-z15
name: 'Equihash',
joulesPerHash: ANTMINER_Z15_WATTAGE / rawHashes(420, 'KH')
},
{ // https://www.asicminervalue.com/miners/strongu/stu-u1-2
name: 'Blake (14r)',
joulesPerHash: STU_U1_PLUSPLUS_WATTAGE / rawHashes(52, 'TH')
},
{ // https://www.nicehash.com/profitability-calculator/nvidia-rtx-3090
name: 'Zhash',
joulesPerHash: RTX_3090_WATTAGE / rawHashes(136.15, 'H')
},
{ // https://www.nicehash.com/profitability-calculator/nvidia-rtx-3090
name: 'KawPow',
joulesPerHash: RTX_3090_WATTAGE / rawHashes(54, 'MH')
},
{ // https://www.asicminervalue.com/miners/goldshell/ck5
name: 'Eaglesong',
joulesPerHash: GOLDSHELL_CK5_WATTAGE / rawHashes(12, 'TH')
}
];
module.exports = getAlgorithms;
module.exports.handler = () => sendJson(getAlgorithms);

42
api/data.js

@ -1,45 +1,23 @@
const sendJson = require('./util/send-json');
const getNiceHashData = require('./nicehash');
const getCoinData = require('./coins');
const getAlgorithms = require('./algorithms');
const getData = async () => {
const [nicehashAlgorithms, coins] = await Promise.all([
getNiceHashData(),
getCoinData()
]);
const algorithms = getAlgorithms();
const getNiceHashForCoin = coin => {
const names = {
'SHA-256': 'sha256asicboost',
Ethash: 'daggerhashimoto',
RandomX: 'RandomXmonero'
const getCoinAlgorithm = coin => {
return algorithms.find(algorithm => algorithm.name.toLowerCase() === coin.algorithm.toLowerCase());
};
const coinAlgorithm = names[coin.algorithm] || coin.algorithm;
return nicehashAlgorithms.find(algorithm => algorithm.name.toLowerCase() === coinAlgorithm.toLowerCase());
};
const getData = async () => {
const coins = await getCoinData();
const data = coins
.filter(coin => {
const nicehash = getNiceHashForCoin(coin);
if (!nicehash) {
// See if we can fix some of these
console.log(coin.symbol, coin.name, coin.algorithm);
}
return nicehash;
})
.filter(coin => getCoinAlgorithm(coin))
.map(coin => {
const nicehash = getNiceHashForCoin(coin);
const hashrateCostPerSecond = (coin.hashrate * nicehash.pricePerHashPerSecond);
const nicehasheable = (nicehash.hashrate / coin.hashrate * 100);
const algorithm = getCoinAlgorithm(coin);
coin.watts = (coin.hashrate * algorithm.joulesPerHash);
return {
...coin,
hashrateCostPerSecond,
nicehasheable
};
return coin;
});
return data;

11
js/format-hashrate.js

@ -1,11 +0,0 @@
const formatHashrate = hashrate => ['H', 'KH', 'MH', 'GH', 'TH', 'PH'].reduce((previous, unit, exponent) => {
const devisor = (1000 ** exponent);
if (hashrate > devisor) {
const value = Math.floor(hashrate / devisor);
return `${value.toLocaleString()} ${unit}/s`;
}
return previous;
});
export default formatHashrate;

12
js/format-units.js

@ -0,0 +1,12 @@
const formatUnits = (originalValue, singleUnit) => ['', 'K', 'M', 'G', 'T', 'P'].reduce((previous, unit, exponent) => {
const devisor = (1000 ** exponent);
if (originalValue > devisor) {
let value = originalValue / devisor;
value = value < 10 ? value.toFixed(2) : Math.floor(value);
return `${value.toLocaleString()} ${unit}${singleUnit}`;
}
return previous;
});
export default formatUnits;

6
js/index.js

@ -6,7 +6,7 @@ import getCoinName from './get-coin-name';
import formatSeconds from './format-seconds';
import coinBlackList from './coin-blacklist';
import formatDollars from './format-dollars';
import formatHashrate from './format-hashrate';
import formatUnits from './format-units';
const BITCOIN_CONFIRMATIONS = 6;
@ -66,7 +66,7 @@ const render = (coins, sortBy) => {
${escapeHTML(`${getCoinName(coin)} (${coin.symbol})`)}
</td>
<td>${escapeHTML(formatDollars(coin.marketCap) || 'Unknown')}</td>
<td>${escapeHTML(`${coin.algorithm} @ ${formatHashrate(coin.hashrate)}`)}</td>
<td>${escapeHTML(`${coin.algorithm} @ ${formatUnits(coin.hashrate, 'H/s')}`)} = ${formatUnits(coin.watts, 'W')}</td>
<td>${escapeHTML(coin.confirmations.toLocaleString())} confs</td>
<td>${escapeHTML(formatSeconds(coin.timeForConfs))}</td>
<td>${escapeHTML(coin.symbol === 'BTC' ? '-' : `${Math.round(coin.multiplier).toLocaleString()}x slower`)}</td>
@ -87,7 +87,7 @@ fetch('https://howmanyconfs.com/api/data')
coins = coins
.filter(coin => !coinBlackList.includes(coin.symbol))
.map(coin => {
const multiplier = (bitcoin.hashrateCostPerSecond / coin.hashrateCostPerSecond);
const multiplier = (bitcoin.watts / coin.watts);
const workTime = (bitcoin.blockTimeInSeconds * BITCOIN_CONFIRMATIONS * multiplier);
const confirmations = Math.ceil(workTime / coin.blockTimeInSeconds);
const timeForConfs = (coin.blockTimeInSeconds * confirmations);

BIN
screenshot.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 229 KiB

After

Width:  |  Height:  |  Size: 409 KiB

4
style.css

@ -2,7 +2,7 @@
body {
color: #333;
min-width: 1024px;
min-width: 1200px;
}
a {
@ -15,7 +15,7 @@ a:hover {
}
.wrapper {
max-width: 1024px;
max-width: 1200px;
margin: 0 auto;
padding: 0 2em;
box-sizing: content-box;

Loading…
Cancel
Save