parent
679831880a
commit
1a67acf443
@ -0,0 +1,82 @@ |
||||
package waitnode |
||||
|
||||
import ( |
||||
"bytes" |
||||
"crypto/sha256" |
||||
"fmt" |
||||
"math" |
||||
"math/big" |
||||
) |
||||
|
||||
var ( |
||||
maxNonce = math.MaxInt64 |
||||
) |
||||
|
||||
const targetBits = 24 |
||||
|
||||
// ProofOfWork represents a proof-of-work |
||||
type ProofOfWork struct { |
||||
Challenge int32 |
||||
target *big.Int |
||||
} |
||||
|
||||
// NewProofOfWork builds and returns a ProofOfWork |
||||
func NewProofOfWork(c int32) *ProofOfWork { |
||||
target := big.NewInt(1) |
||||
target.Lsh(target, uint(256-targetBits)) |
||||
|
||||
pow := &ProofOfWork{c, target} |
||||
|
||||
return pow |
||||
} |
||||
|
||||
func (pow *ProofOfWork) prepareData(nonce int) []byte { |
||||
data := bytes.Join( |
||||
[][]byte{ |
||||
pow.Challenge., |
||||
IntToHex(int64(targetBits)), |
||||
IntToHex(int64(nonce)), |
||||
}, |
||||
[]byte{}, |
||||
) |
||||
|
||||
return data |
||||
} |
||||
|
||||
// Run performs a proof-of-work |
||||
func (pow *ProofOfWork) Run() (int, []byte) { |
||||
var hashInt big.Int |
||||
var hash [32]byte |
||||
nonce := 0 |
||||
|
||||
fmt.Printf("Mining the block containing \"%s\"\n", pow.block.Data) |
||||
for nonce < maxNonce { |
||||
data := pow.prepareData(nonce) |
||||
|
||||
hash = sha256.Sum256(data) |
||||
fmt.Printf("\r%x", hash) |
||||
hashInt.SetBytes(hash[:]) |
||||
|
||||
if hashInt.Cmp(pow.target) == -1 { |
||||
break |
||||
} else { |
||||
nonce++ |
||||
} |
||||
} |
||||
fmt.Print("\n\n") |
||||
|
||||
return nonce, hash[:] |
||||
} |
||||
|
||||
// Validate validates block's PoW |
||||
func (pow *ProofOfWork) Validate() bool { |
||||
var hashInt big.Int |
||||
|
||||
data := pow.prepareData(pow.challenge.Nonce) |
||||
hash := sha256.Sum256(data) |
||||
hashInt.SetBytes(hash[:]) |
||||
|
||||
isValid := hashInt.Cmp(pow.target) == -1 |
||||
|
||||
return isValid |
||||
} |
Loading…
Reference in new issue