Post on 25-Jan-2023
Joshua Elkington
Analysis of Selfish Bitcoin Mining Strategies Abstract Bitcoin is a decentralized peer-‐to-‐peer payment system that has the potential to disrupt the financial industry. In order for the Bitcoin network to function properly, people within the network need to follow the protocol and contribute computing power. However, selfish strategies can be used to disproportionately increase one’s payoff relative to their computational power. Three approaches are used to analyze selfish mining strategies in the Bitcoin network in order to determine when this strategy will dominate. Introduction
Bitcoin Overview Bitcoin is an open source decentralized peer-‐to-‐peer payment system uses cryptographic keys to control the creation and transfer of fiat currency. Normally, uppercase Bitcoin refers to the network or the protocol, while lowercase bitcoin refers to the actual currency. Bitcoins are created through a process called mining where computers within the Bitcoin network provide computing power to verify and records transactions in the public Bitcoin ledger in exchange for new Bitcoins and transaction fees. This public log is called the blockchain that records all transactions between Bitcoin clients. The more mining power a miner has, the better their chances of solving the cryptographic puzzle before other miners. This blockchain is essential for Bitcoin to be decentralized.
Figure 1 Bitcoin growth curve Miners solve a cryptographic hash problem in order to obtain new bitcoins and transaction fees. The difficulty of the problem is adjusted in order to ensure that the number of solutions found for a given unit of time is constant around 6 solutions per hour. When a solution is found, the user who solved the hash can broadcast the existence of this new solution along with other information into a new “block.” Presently, each new block creates 25 new bitcoins; however, approximately every four years the number of bitcoins that can be mined per block will be reduced by 50%. The block rewards incentivizes people to perform computation work to generate blocks that record the transaction history of the whole bitcoin network. Ultimately, the number of bitcoins is limited to 21 million (Figure 1,2). So over time, the block reward to decrease to zero, as a result, miners will have to be rewarded with higher transaction fees. For example, a user sending bitcoins will pay a transaction fee that will be won by the person who mines the next block. The higher transaction fee provided by the user, the miner will have more incentive to solve the next block and included the transaction into the Bitcoin ledger more quickly (Figure 2).
A B
C Figure 2 Bitcoin statistics (A) Transaction fees within Bitcoin network (B) Number of transaction in network (C) Bitcoin Market capitalization
Figure 3 Overview of Bitcoin transactions and mining
When making bitcoin transactions, the Bitcoin protocol uses public key cryptography to make and verify digital signatures in order to guarantee that one user cannot create transactions in other people’s names to spend bitcoins they do not own. Within this transaction system, each user has one or more addresses with associated public and private keys (Figure 3). Only the user with the private key can sign a transaction that sends their bitcoins to another user; however, other users such as miners using the public key can validate this transaction. Within the network, each balance of bitcoins is associated with an address and its public and private key pair. The bitcoins belong to the user with access to the private key. Using bitcoins doesn’t require the user of personal identifying marks because only the keys are used to verify transactions between users. Each user can have theoretically an unlimited number of addresses; therefore, a user can hide their identity by used a new address for each transaction. For example, lets suppose there is a user named Ian that wants to send bitcoins to another user, Dan. So, Dan sends his address to Ian then Ian combines this address with an amount of bitcoins to send a transaction message to the bitcoin network. Ian signs this transaction message with his private key and sends her
public key to the network for transaction verification. If Dan wanted to send these bitcoins to other users, he would go through the same process. Each user’s private key ensures that the owner of the bitcoins only makes transactions. However, this system causes bitcoin transactions to be irreverisible because if someone other than Ian sent bitcoins to Dan and Dan sent bitcoin to other users, the network assumed that the transaction was verified because the private key was used to sign the transaction. As more blocks are generated, transactions are added to the public ledger thus Ian wouldn’t be able to recover his bitcoins if his private key was compromised. In order to prevent double spending of the same bitcoins, the Bitcoin network sends the details of any transaction to all other users, and the growing chain of blocks with the history of all transactions are collectively maintained by all users. Only the longest chain of valid blocks is extended further so Dan can know that if the transaction made by Ian has been added to the longest chain of blocks, he can be confident that the transfer of bitcoins has been accepted by the majority of users within the network thereby preventing Ian from sending the coin to other users because the transaction to Dan has been recorded permanently. The only way Ian could spend the bitcoins again is to have 51% or more of the computing power of the Bitcoin network. This type of attack is called a “51% attack” where a user can reverse their own transactions, which allows double spending of bitcoins A common criticism of bitcoin is its built in deflation because only a limited amount of bitcoins will be made available. This can lead to a deflationary spiral where rampant deflation can cause the collapse of a currency. Deflation is the decline of price levels because of the increasing value of a currency. A deflationary spiral occurs when the value of a currency relative to goods and services increases due to hoarding of the currency. As the currency’s value increase, people have more incentive to hoard the currency. If all the currency is hoarded and no transactions are made, the price of good and services will decrease to zero thus destroying the economic system of the currency. As the value of bitcoins increases, users are more likely to hold onto bitcoins with the hope of cashing out for a higher amount. So if no transactions are made with bitcoin, then the currency is useless because the market for goods using bitcoin will be non-‐existent. Furthermore, the price volatility of bitcoin is barrier of widespread adoption of the currency. Although this volatility doesn’t affect the ability of Bitcoin to act as a payment processor, it does prevent bitcoin from being a store of value.
Figure 4 Example block in the Bitcoin blockchain in JSON (JavaScript Object
Notation).
Bitcoin Protocol In order for the Bitcoin protocol to function properly, the majority of the miners have to be honest, which means that they broadcast a solution to the cryptopuzzle to the entire network and follow the code of the protocol. The “51%” attack is a form of dishonesty because a group of colluding miners come together to take control of the majority of the network’s computational power to double spend bitcoins and prevent other transactions. Miners can form groups called mining pools to use their collective mining power to increase their chances of obtaining bitcoins. Within these pools, all members contribute computing power to solve a cryptopuzzle and share the reward proportional to their contribution. Despite no clear evidence that these mining pools do not follow the protocol, there is a still a chance that a mining pool can deviate from it and use certain strategies to increase their payoff. The protocol is set up to reward miners proportional to the mining power of the network they possess. It’s believed that a honest miner in a large mining pool will earn the same amount of bitcoins as in smaller pool over a long period of time. Using this logic, mining pools would pose no threat to the integrity of the protocol because the size of the pool wouldn’t affect a miner’s gain in overall bitcoins. So the protocol relies on the assumption that miners will cooperate because they want to see their block solutions incorporated into the longest blockchain (Figure 4).
{"hash":"00000000000000f38...",
"prev_block":"00000000000000c6d...",
"time":1354114900,
"difficulty":436527338,
"nonce":282240624,
"tx":[
{”hash":"5ca...",
"in":[
{"prev_out":
{"hash":"000...",},
}
],
"out":[
{"value":"50.53620000",
"scriptPubKey":"27a1..."
}
]
},
...
]
}
Figure 1: A schematic block in the block chain, represented as JSON (JavaScriptObject Notation). Some metadata has been left out and truncated values aremarked by ellipses.
way to know if the coins he is being given have been previously used to paysomeone else.
To prevent double spending, Bitcoin players engage in a peer-to-peer proto-col that implements a distributed timestamp service providing a fully-serializedlog of every Bitcoin transaction ever made. Transactions are organized in the loginto blocks, which contain a sequence number, a timestamp, the cryptographichash of the previous block, some metadata, a nonce, and a set of valid Bitcointransactions. A schematic representation of an individual block is shown in Fig-ure 1. The blocks form a hash chain: each new block contains the cryptographichash of its predecessor, allowing anyone to verify that no preceding block hasbeen modified. The block chain contains backward links but not forward links(a block cannot link forward to a future block that has not yet been created) sothere is a unique path backward from each block to the beginning of the log (thegenesis block) but the forward path from a block might not be unique. Thusthe log has the form of a tree whose branches fork as it grows. The block chainis shown in Figure 2.
Any player may choose to become a miner and mine new blocks that addnew transactions to the log. A new block is a valid addition to the log if itsnonce is chosen so that the new block’s hash is less than a target value. This isa form of proof-of-work puzzle, a computation that is thought to be di�cult toperform but whose result is easy to verify. The solution to a proof-of-work puzzlee↵ectively asserts that someone has expended a certain level of e↵ort [12, 17, 6].
The Twelfth Workshop on the Economics of Information Security (WEIS 2013)
Washington, DC, June 11-12, 2013
4
However, if miners are not honest, they can form mining pools and use selfish mining strategies gain a disproportionate payoff relative to the amount of network computing power they own. A mining pool could create a fork of the blockchain by not broadcasting their discovering of solution for blocks until after a certain time. The honest miners would still mine on the original blockchain while the selfish mining pool would mine on the private fork of the blockchain. If this selfish pool discovers more blocks than the rest of the network, its private fork will become longer than the original blockchain. If the length of the original blockchain nears the length of the private fork, then the selfish mining pool would reveal the solution to their blocks in order to publish the longest blockchain on the network, which will be accepted by the other Bitcoin clients. As a result, honest miners would waste computational power trying to solve blocks if a selfish mining pool with enough computing power revealed their longer, private fork. Overtime if selfish mining pools gain a disproportionate amount of bitcoins, rational miners will join selfish mining pools thereby compromising the Bitcoin protocol. The Bitcoin protocol is open source code so the rules of the network can be rewritten in order to hinder use of selfish mining strategies. So this paper tries to determine under what conditions selfish mining strategies will dominate the network.
Figure 5 Blockchain where first block is genesis. Mining occurs on the longest branch of the branching tree while shorter branches with are considered invalid
Methods
Investigating Selfish Mining with a SIS model In order to study the two different mining strategies, a SIS model (Figure 5) was created to mimic the behavior of mining pools deciding which strategy to choose. The susceptible population can be understood as mining pools using the honest strategy to obtain bitcoins, while the infected population would be the selfish
Figure 2: An example abstract blockchain. The genesis (first) block is on theleft. Mining occurs on the longest branch of the branching tree. Other branchesand branches with invalid blocks are ignored.
The specific proof-of-work in Bitcoin is taken from Hashcash [3]. The di�cultyof the proof-of-work puzzle is adjusted periodically by an adaptive algorithmbased on the recent block chain history to maintain the long-term invariantthat one new block be mined every ten minutes on average.
The mining mechanism has the property that if there are two branches ofthe tree, with a separate group of miners growing each branch, then the branchwhose miners have more computational power will grow more quickly5. In asense, miners vote for a branch by devoting their mining e↵ort to extending it,and the Bitcoin rules say that the longest branch should be treated as the onlyvalid one.
When a user Alice wishes to transfer Bitcoins to Bob, she creates and signsa transaction object and broadcasts it to her peers in the Bitcoin peer-to-peernetwork. The peers then rebroadcast it, e↵ectively flooding the network withall known pending transactions.6 All of the miners (that is, players who alsoelect to mine) then attempt to create a new block with the pending transactionsthey know about.
New Bitcoins can only be created via the mining process. Each miner addsto their prospective block a special transaction creating a number of rewardBitcoins which may be paid to anyone (but which typically are paid to theminer). This provides an incentive for miners to engage in mining. The numberof Bitcoins created this way is adjusted on a predetermined schedule in which thereward is halved each time 210000 more blocks have been mined. The original
5Because miners search randomly for puzzle solutions, a branch supported by fewer mining
resources might happen to grow faster in the short run, but in the long run the branch with
more resources will always win. Prudent Bitcoin participants will wait for a while before
accepting one branch as valid, to eliminate the possibility that the longest branch is short-
term lucky and will lose in the long run. Karame, Androulaki, and Capkun [16] describe
attacks that are possible if participants do not wait.
6But see Babaio↵ et al. [2], which posits that if a transaction has a transaction fee, this
transaction flooding itself might not be incentive-compatible. In Section 4.2, we examine the
issue of incentives from transaction fees from a di↵erent perspective, arguing that such fees
might not be a reasonable basis for the mining game.
The Twelfth Workshop on the Economics of Information Security (WEIS 2013)
Washington, DC, June 11-12, 2013
5
mining pools that decide to hide there block discoveries in order to maximize their bitcoin payoff.
Figure 6 SIS Model overview where a susceptible individual or mining pool become infected but can recover and become susceptible again
The SIS model doesn’t contain immunity to infection and allows infected individuals to recover and become immediately susceptible again. This means that mining pools can dynamically switch between honest and selfish mining strategies.
Figure 7 SIS Model For the SIS model (Figure 6), the initial population (N) of mining pools is assumed to be 1000. The constants within the SIS model are beta, mu, and gamma. Beta represents the contact rate between the selfish and honest strategies for each mining pool, which means the frequency of having to decide what strategy to use for each block. Beta was assumed to be the inverse of N. Gamma is the average period of time the selfish mining strategy “infects” a mining pool, which is assumed to be the inverse value of time for finding a block of 600 seconds. The constant mu is the “death” rate of each strategy, which is assumed to be the same for both strategies and the inverse value of N.
Using Replicator Dynamics to Find the Optimal Timing of Selfish Mining A model using replicator dynamics was used to predict the optimal selfish mining strategy (Figure 8). Replicator dynamics models the probability of using a certain strategy. If the payoff of a particular strategy is larger than the average payoff then the probability of people within a population using this strategy will increase. If the strategy’s payoff is less than the average payoff, then the strategy will decrease within a population. This will occur for all strategies until equilibrium is reached over time.
Figure 8 Replicator dynamics model overview
Within the replicator dynamics model, three strategies were used: the honest strategy and two variants of the selfish mining strategy. The selfish strategies differ between when they reveal their hidden block. One strategy reveals after discovering the second block, while the other reveals after finding the third block. The initial
find yourself losing a lot of money playing a game you will change the way that you playit until that doesn’t happen anymore.
A simple model that captures this idea is the following set of ordinary differentialequations. These equations are called the “replicator dynamics”, and were introduced byTaylor and Jonker.1 The model is
dp
dt
= p
✓Payoff1 � Payoff
◆, (1)
dq
dt
= q
✓Payoff2 � Payoff
◆. (2)
HerePayoff1 = pa + qb
andPayoff2 = pc + qd.
These are the payoffs expected from playing each of the two strategies. The quantity Payoffis the average payoff. This is given by
Payoff = pPayoff1 + qPayoff2.
The model therefore says that if the payoff of a particular strategy is larger than the averagepayoff, the probability of playing this strategy will grow, whereas if the payoff is less thanthe average the probability of playing this strategy will shrink. The question we need toconsider is whether these dynamics will lead to an equilibrium, and if it agrees with theNash equilibrium discussed in class.
Exercise 1Start with the Python program we gave you for solving the SIR model. Modifythese equations to solve the replicator dynamics described above. Note that inEqs. 1 & 2 we have that p + q = 1, because the total probability of choosing onestrategy or the other must sum to unity. Thus when you choose initial conditions,you need to choose them so that the initial p + q = 1.
To simulate the equation properly, you need to choose different examples for the matrixA. We propose you start with the three examples we discussed in class.
1There is a very nice description of these dynamics in Martin Nowak’s book “Evolutionary dynamics”,and in his course in the math department.
2
find yourself losing a lot of money playing a game you will change the way that you playit until that doesn’t happen anymore.
A simple model that captures this idea is the following set of ordinary differentialequations. These equations are called the “replicator dynamics”, and were introduced byTaylor and Jonker.1 The model is
dp
dt
= p
✓Payoff1 � Payoff
◆, (1)
dq
dt
= q
✓Payoff2 � Payoff
◆. (2)
HerePayoff1 = pa + qb
andPayoff2 = pc + qd.
These are the payoffs expected from playing each of the two strategies. The quantity Payoffis the average payoff. This is given by
Payoff = pPayoff1 + qPayoff2.
The model therefore says that if the payoff of a particular strategy is larger than the averagepayoff, the probability of playing this strategy will grow, whereas if the payoff is less thanthe average the probability of playing this strategy will shrink. The question we need toconsider is whether these dynamics will lead to an equilibrium, and if it agrees with theNash equilibrium discussed in class.
Exercise 1Start with the Python program we gave you for solving the SIR model. Modifythese equations to solve the replicator dynamics described above. Note that inEqs. 1 & 2 we have that p + q = 1, because the total probability of choosing onestrategy or the other must sum to unity. Thus when you choose initial conditions,you need to choose them so that the initial p + q = 1.
To simulate the equation properly, you need to choose different examples for the matrixA. We propose you start with the three examples we discussed in class.
1There is a very nice description of these dynamics in Martin Nowak’s book “Evolutionary dynamics”,and in his course in the math department.
2
find yourself losing a lot of money playing a game you will change the way that you playit until that doesn’t happen anymore.
A simple model that captures this idea is the following set of ordinary differentialequations. These equations are called the “replicator dynamics”, and were introduced byTaylor and Jonker.1 The model is
dp
dt
= p
✓Payoff1 � Payoff
◆, (1)
dq
dt
= q
✓Payoff2 � Payoff
◆. (2)
HerePayoff1 = pa + qb
andPayoff2 = pc + qd.
These are the payoffs expected from playing each of the two strategies. The quantity Payoffis the average payoff. This is given by
Payoff = pPayoff1 + qPayoff2.
The model therefore says that if the payoff of a particular strategy is larger than the averagepayoff, the probability of playing this strategy will grow, whereas if the payoff is less thanthe average the probability of playing this strategy will shrink. The question we need toconsider is whether these dynamics will lead to an equilibrium, and if it agrees with theNash equilibrium discussed in class.
Exercise 1Start with the Python program we gave you for solving the SIR model. Modifythese equations to solve the replicator dynamics described above. Note that inEqs. 1 & 2 we have that p + q = 1, because the total probability of choosing onestrategy or the other must sum to unity. Thus when you choose initial conditions,you need to choose them so that the initial p + q = 1.
To simulate the equation properly, you need to choose different examples for the matrixA. We propose you start with the three examples we discussed in class.
1There is a very nice description of these dynamics in Martin Nowak’s book “Evolutionary dynamics”,and in his course in the math department.
2
populations of mining pools for each strategy were assumed to be the same. The payoff of mining the next block after hiding the first block was assumed to decrease the value of the previous block by one-‐half. The payoff after hiding two blocks decreases by one-‐third because of the increased probability of the honest miners catching up and negating the value of the hidden blocks.
Understand the effects of Payoffs on Mining Pool populations With the guide to try to find a possible solution to prevent the spread of selfish mining strategies within the Bitcoin network, a simulation was run to try to understand how payoff systems might effect the population of the Bitcoin network. Three different payoff systems were used: random split, winner takes 75% of the reward, and winner takes all of the reward. The simulation assumed that the population of mining pools is fixed at 100 and the probability of using honest or selfish strategies adds up to 1. The simulation finds two players that have different probability of using the honest or selfish strategies as determined by a Gaussian distribution. For each payoff system, the players decide what strategy to use next over 500 steps. The payoff percentiles of mining pool that use a combination of strategies are plotted to determine what payoff system will help decrease the profitability of the selfish mining strategy. Results and Discussion SIS Model The SIS model predicts that the selfish mining strategy will “infect” and dominate the population of all mining pools. The rate that the selfish mining strategy “infects” the population depends on the initial population of mining pools that use the honest and selfish mining strategies (Figure 9). In order to determine if the “death” rate of each strategy may influence the equilibrium values for each strategy, each strategy was giver a different rate of death where the rate for the selfish strategy was lower than the rate for the honest strategy. However, there was no effect on the equilibrium values of the two strategies indicating that selfish strategy will dominate a population of mining pools despite differentials rates of strategy loss. The SIS model predicts that the selfish mining strategy will dominate a population of mining pools.
A B
C D Figure 9 SIS Model Results (A) Initial population using honest strategy (out of 100): 99 and Initial population using honest strategy (out of 100): 1 (B) Initial population using honest strategy (out of 100): 99 and Initial population using honest strategy (out of 100): 1 and beta=(1.0/100) (C) Initial population using honest strategy (out of 100): 90 and Initial population using honest strategy (out of 100): 10 (D) Initial population using honest strategy (out of 100): 50 and Initial population using honest strategy (out of 100): 50 Replicator Dynamics The replicator dynamics model predicted that the majority of a population would use the selfish mining strategy if the only other strategy were the honest strategy. However, at equilibrium both strategies remained within the population despite the higher payoff from selfish strategy (Figure 10)
Figure 10 Replicator Dynamics of honest and selfish mining strategies When 2 variants of the selfish mining strategy were added to the model with one strategy revealing the second block discovered and the other revealing after the third block is discovered (Figure 11). The selfish strategy where the blocks are revealed after discovering the second block dominated the population, while the other two strategies decreased to zero. This reveals that if these are the only two selfish strategies available then revealing the hidden blocks after discovering the second one is the optimal strategy. This could be a realistic modeling of Bitcoin mining strategies because the probability of discovering three or more blocks than the network is high improbable unless a mining pool as a majority of the computing power of the network.
Figure 11 Replicator Dynamics of honest and two variants of selfish mining strategies where one reveals after finding the first block after the hidden block and one that reveals after finding the second block after the hidden block.
Simulation For the simulation of the effects of payoff systems on the use of strategies of each mining pool, a payoff system based on splitting up the block randomly between mining pools still results in the domination by mining pools that predominately use the selfish strategy, but pools that predominately use the honest strategy still persist within the population (Figure 12).
A
B Figure 12 Strategy growth with random split payoff system (A) Plot of the certain percentiles within the population (B) Table of the beginning, middle, and final values of the populations for each population percentile
Payoff systems based on rewarding the block’s bitcoin to a winner or giving the majority to the winner induces mining pools that predominately use the selfish strategy to dominate while pools that mostly use the honest strategy die off to zero (Figure 13, 14). This simulation shows that the current payoff system used by the Bitcoin network, winner take all, allows selfish mining strategies to dominate all other strategies. Possible modifications to the Bitcoin payoff system that would be useful to prevent the spread of selfish strategies could be randomly splitting up the block reward amongst all the mining pool. But this would decrease the incentive to provide computational power to confirm transactions; however, a mixture of payoff systems could be used where a random split is used for every other block to decrease the incentive for mining pools to hide their discovered blocks.
A
B Figure 13 Strategy growth with winner take 75% payoff system (A) Plot of the certain percentiles within the population (B) Table of the beginning, middle, and final values of the populations for each population percentile
A
B Figure 14 Strategy growth with winner-‐take-‐all payoff system (A) Plot of the certain percentiles within the population (B) Table of the beginning, middle, and final values of the populations for each population percentile Conclusion The analysis shows that the selfish mining strategy will dominate the Bitcoin network. So modifications to the protocol will have to be made to maintain the integrity of the network. A possible solution could be modifying the payoff system to include random split of a block’s reward between all miners for a certain frequency of blocks to disrupt the incentive of using the selfish mining strategy. Bitcoin has the potential to disrupt the financial industry along with redefining the way society governs organizations. In order to ensure the decentralization of the network, miners need to be properly incentivized to provide computing power. The protocol needs to prevent miners from using selfish mining
strategies that may reduce the integrity of the entire network. A strategy of not revealing hidden blocks until a later time that renders the computing power of other miners worthless is a type of selfish strategy. The models used show that selfish strategies are a threat to the Bitcoin network, and a restructuring of the Bitcoin protocol must begin in order to prevent the Bitcoin network from being exploited. If the network’s safety can be ensured then more users will feel comfortable to adopt this new technology. As a result, Bitcoin would grow into something that can beneficially disrupt society. References Bitcoin Wiki https://en.bitcoin.it/wiki/Main_Page Bitcoin Forum https://bitcointalk.org Bitcoin Foundation https://bitcoinfoundation.org Economics Simulation http://nbviewer.ipython.org/url/norvig.com/ipython/ Economics.ipynb Blockchain https://blockchain.info Code SIS import numpy as np import matplotlib.pyplot as plt from scipy.integrate import odeint # Constants in model #beta = contact rate between selfish and honest strategies beta=(1.0/1000) #1/gamma = average infectious period, which is time to find a block of 10 minutes (600 secs) gamma=(1.0/600.0) # mu = death rate of strategies mu=(1/1000) #initial population of 1000 mining pool N=1000 # Function to calculate derivatives of S(t), I(t), and R(t) def deriv(x,t): hon1=beta*x[0]*x[1] hon2=mu*(N-‐x[0]) sel1=gamma*x[1] sel2=mu*x[1] return np.array([-‐hon1+hon2+sel1,hon1-‐sel1-‐sel2])
# Solve ODE using the "odeint" library in SciPy time=np.linspace(0,100,5000) #assume everyone is honest initially xinit=np.array([90,10]) x=odeint(deriv , xinit , time) # Plot the solutions plt.figure() p0,=plt.plot(time,x[:,0]) p1,=plt.plot(time,x[:,1]) plt.legend([p0,p1],["Honest","Selfish"]) plt.xlabel('t (Seconds)') plt.ylabel('Mining Pools') plt.show() Replicator 2 strategies: import numpy as np import matplotlib.pyplot as plt from scipy.integrate import odeint # Constants in model a=25 b=0 c=25/2 d=25 # 2 strategies: p0=honest and p1=selfish for i in range(1,10): def deriv(x,t): p0 = x[0]*a+x[1]*b p1 = x[0]*c+x[1]*d bar = x[0]*p0+x[1]*p1 delp0 = x[0]*(p0-‐bar) delp1 = x[1]*(p1-‐bar) return np.array([delp0,delp1]) # Solve ODE using the "odeint" library in SciPy time=np.linspace(0,1,5000) xinit=np.array([5.0,5.0]) x=odeint(deriv ,xinit ,time) # Plot the solutions plt.figure() p0,=plt.plot(time,x[:,0]) p1,=plt.plot(time,x[:,1]) plt.legend([p0,p1],["Honest","Selfish"]) plt.xlabel("Block") plt.ylabel("Strategy Payoff")
plt.show() 3 strategies: import numpy as np import matplotlib.pyplot as plt from scipy.integrate import odeint # Constants in model a=25 b=0 c=0 d=25/2 e=25 f=0 g=25/3 h=25/2 i=25 # 3 strategies: p0=honest and p1=selfish and reveal after discovering 2nd block and p2= selfish and reveal after discovering 3rd block for i in range(1,10): def deriv(x,t): p0 = x[0]*a+x[1]*b+x[2]*c p1 = x[0]*d+x[1]*e+x[2]*f p2 = x[0]*g+x[1]*h+x[2]*i bar = x[0]*p0+x[1]*p1 delp0 = x[0]*(p0-‐bar) delp1 = x[1]*(p1-‐bar) delp2 = x[2]*(p2-‐bar) return np.array([delp0,delp1,delp2]) # Solve ODE using the "odeint" library in SciPy time=np.linspace(0,1,5000) xinit=np.array([5.0,5.0,5.0]) x=odeint(deriv ,xinit ,time) # Plot the solutions plt.figure() p0,=plt.plot(time,x[:,0]) p1,=plt.plot(time,x[:,1]) p2,=plt.plot(time,x[:,2]) plt.legend([p0,p1,p2],["Honest","Selfish-‐Reveal after 1st","Selfish-‐Reveal after 2nd"]) plt.xlabel("Block") plt.ylabel("Strategy Payoff") plt.show() Simulation
import random import matplotlib import matplotlib.pyplot as plt import numpy as np #mining pools N = 100 #payoff mu = 1 def sample(dis, N=N, mu=mu): return normalize([dis() for _ in range(N)], mu * N) def gauss(N=N, sigma=N/5): return random.gauss(N, sigma) def normalize(numbers, total): factor = total / float(sum(numbers)) return [x * factor for x in numbers] #interactions between mining pools def anyone(pop): return random.sample(range(len(pop)), 2) def random_split(X, Y): pot = X + Y m = random.uniform(0, pot) return m, pot -‐ m def winner_take_most(X, Y, most=75/100): #.75 of pot pot = X + Y m = random.choice((most * pot, (1 -‐ most) * pot)) return m, pot -‐ m def winner_take_all(X, Y): return winner_take_most(X, Y, 1.0) def simulate(population, transaction, interaction, T, percentiles, record_every): results = [] for t in range(T): i, j = interaction(population) population[i], population[j] = transaction(population[i], population[j]) if t % record_every == 0: results.append(record_percentiles(population, percentiles)) return results def report(distribution=gauss, transaction=random_split, interaction=anyone, N=N, mu=mu, T=5*N, percentiles=(1, 10, 25, 33.3, 50, -‐33.3, -‐25, -‐10, -‐1), record_every=25): population = sample(distribution, N, mu) results = simulate(population, transaction, interaction, T, percentiles, record_every) print('Simulation: {} * {}(mu={}) for T={} steps with {} doing {}:\n'.format( N, name(distribution), mu, T, name(interaction), name(transaction))) fmt = '{:6}' + '{:10.2f} ' * len(percentiles)
print(('{:6}' + '{:>10} ' * len(percentiles)).format('', *map(percentile_name, percentiles))) for (label, nums) in [('start', results[0]), ('mid', results[len(results)//2]), ('final', results[-‐1])]: print fmt.format(label, *nums) for line in zip(*results): plt.plot(line) plt.show() def record_percentiles(population, percentiles): population = sorted(population, reverse=True) N = len(population) return [population[int(p*N/100.)] for p in percentiles] def percentile_name(p): return ('median' if p==50 else '{} {}%'.format(('top' if p>0 else 'bot'), abs(p))) def name(obj): return getattr(obj, '__name__', str(obj)) #report(gauss,random_split) #report(gauss,winner_take_most) report(gauss, winner_take_all)