I'm trying to write a program which concurrently mines a block of bitcoin. I have set it up so that each goroutine has an initial starting nonce each of which is a fraction of 4 ie. 2**64 - 1 (max number of uint64 type) / 1 or 2 or 3 or 4.
Only one of these miners will come across the correct nonce and when that happens I would like it to pass it to the miner manager through a channel and when this happens I would like the other 3 miners to stop what they're doing.
The only problem is I have no idea how to destroy a running goroutine, or if there is even a way to do what I'm asking.
func miner(blockNumber int, transactions string, previousHash string, zeroPrefix string, startNonce uint64, nonceChan chan uint64, hashChan chan string) {
var text string
var newHash string
for {
text = strconv.Itoa(blockNumber) + transactions + previousHash + strconv.FormatUint(startNonce, 10)
newHash = encrypt(text)
if startswith(newHash, zeroPrefix) {
nonceChan <- startNonce
hashChan <- newHash
close(nonceChan)
close(hashChan)
break
} else {
startNonce++
}
}
}
func mine(blockNumber int, transactions string, previousHash string, zeroPrefix int) Block {
var prefixString string
var newHash string
var nonce uint64
var startNonce uint64
nonceChan := make(chan uint64)
hashChan := make(chan string)
for i := 0; i < zeroPrefix; i++ {
prefixString += "0"
}
start := time.Now()
for i := 0; i < 4; i++{
// This line is for deciding at what nonce value a miner should start at.
startNonce = uint64((float64(i) / 4) * math.Pow(2, 64))
go func() {
fmt.Println("Started miner with start nonce of", startNonce)
miner(blockNumber, transactions, previousHash, prefixString, startNonce, nonceChan, hashChan)
}()
}
nonce = <- nonceChan
newHash = <- hashChan
// Here is where I would like to destroy the other three miners
block := Block{
blockNumber,
transactions,
previousHash,
newHash,
nonce,
zeroPrefix,
time.Since(start),
}
return block
}