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