以太坊防篡改验证的交流

1 为什么删了以后重启没办法挖矿,是因为创世块都被删了,你重新init一下就ok了。fullnode和lightnode工作原理很多不同。。,lightnode一般就是不挖矿的
你测试当然是都得测试。
2 怎么样整个区块的数据没办法恢复
只要让广播的区块无法通过验证就行了这样就硬分叉了,比如说 你试下篡改未来的区块,比如下一个挖到的块你把root改
,就会硬分叉。这个你有具体的日志信息?开个verbosity 5看下。还有一个点是 你是怎么篡改的

3 那如果改或者删除已经生成的数据呢?把大部分节点的Ldb都删掉,整个区块链的数据还是不会有影响吗? 我的篡改一般就是删除一些数据

这个真的不好说 因为如果你是把ldb文件打开删数据 因为本身是二进制文件,你随机删的话不知道删的是什么,。。一般是这样的话处理方法就是把数据库删掉重新init。你最好还是用专门的api来查数据库来针对性篡改比较好

4我是把源码一些api提取出来写的篡改脚本,一些现成的func可以直接用
这里写图片描述

这里写图片描述

这里写图片描述

4这个你要用的test.go话得把geth整个源码拷贝一份到你的GOROOT下。。。

package main

import (
    "encoding/hex"
    "fmt"
    "math/big"

    "github.com/ethereum/go-ethereum/ethdb"
    // "github.com/ethereum/go-ethereum/trie"
    "github.com/ethereum/go-ethereum/common"
    "github.com/ethereum/go-ethereum/core"
    "github.com/ethereum/go-ethereum/core/state"
    "github.com/ethereum/go-ethereum/core/types"
    "github.com/ethereum/go-ethereum/rlp"
)

func main() {

    db, _ := ethdb.NewLDBDatabase("/Users/reimu/eth/chain/geth/chaindata", 128, 128)
    defer db.Close()

    fmt.Println(*db)
    fmt.Println(db.Path())

    testHash := common.HexToHash("1ff83e56e61474045300be48bfafa75f26b529f2b431ced50f9fb95179f552ef") // stateRoot from eth.getBlock()
    StateDB, _ := state.New(testHash, db)                                                            // Result in a *StateDB

    Addr := common.HexToAddress("67f1b0fde05a37ee895998e903e8242e63d036e0") // Contract Addr

    // This key is the key of your target. It can be found by the result of ForEachStorage2()
    key := common.Hash{168, 196, 212, 195, 62, 53, 105, 154, 143, 63, 17, 71, 81, 9, 0, 148, 77, 246, 224, 215, 137, 180, 15, 117, 116, 123, 19, 254, 236, 211, 171, 250}

    // // StorageTrie()
    // storageTrie := StateDB.StorageTrie(Addr)
    // fmt.Println(storageTrie)

    // // GetStateObject()
    StateObject := StateDB.GetStateObject(Addr)
    //StateObject.GetState(db, key)

    // // ForEachStorage()
    // count := 0
    // callCount := func(key, value common.Hash) bool{
    //  count++
    //  fmt.Println("NO. ", count, ":")
    //  fmt.Println("key: ", key)
    //  fmt.Println("value: ", value,"\n")
    //  return true
    // }
    // StateObject.ForEachStorage(callCount)
    // fmt.Println("Total: ", count)

    StateObject.ForEachStorage2()

    originalValue := "{\"Date\": \"2017-06-13 21:38:44\", "
    // originalValueByte := []byte(originalValue)
    // original := hex.EncodeToString(originalValueByte)
    // originalByte := common.FromHex("0x" + original) // Decoded
    // originalByteEncoded ,_ := rlp.EncodeToBytes(originalByte) //Encoded
    // fmt.Println(originalByte)
    // fmt.Println(common.BytesToHash(originalByteEncoded))  //Decoded
    // fmt.Println(originalByteEncoded)

    modifiedValue := "{\"Date\": \"2017-06-15 21:38:44\", "
    modifiedValueByte := []byte(modifiedValue)
    modified := hex.EncodeToString(modifiedValueByte)
    modifiedByte := common.FromHex("0x" + modified)
    modifiedByteEncoded, _ := rlp.EncodeToBytes(modifiedByte)

    fmt.Println("Tampering:")
    fmt.Println("OriginalData: ", originalValue)
    fmt.Println("ModifiedValue:", modifiedValue)
    fmt.Println("modifiedvalueRLPDecodeHex: ", "0x"+modified)
    fmt.Println("modifiedvalueRLPDecodeByte: ", modifiedByte)
    fmt.Println("modifiedvalueRLPEncodeByte: ", modifiedByteEncoded)
    /* BytesToHash() is exactly the RLP Decoder, therefore modifiedByteEncoded == modifiedByte */
    fmt.Println("HashValue sent to SetState(): ", common.BytesToHash(modifiedByteEncoded))

    /*  Normally currentBlock.Root() === common.ToHex(hash[:]) */

    hash := StateDB.GetHash()
    fmt.Println(hash)
    fmt.Println(common.ToHex(hash[:]))

    currentBlockHash := core.GetHeadBlockHash(db)
    currentBlockNumber := core.GetBlockNumber(db, currentBlockHash)
    currentBlock := core.GetBlock(db, currentBlockHash, currentBlockNumber)
    currentReceipts := core.GetBlockReceipts(db, currentBlockHash, currentBlockNumber)
    tamperBlock := types.NewBlock(currentBlock.Header(), currentBlock.Transactions(), currentBlock.Uncles(), currentReceipts)

    /*   Tampering!!!  */
     (1) Change State
    StateObject.SetState(db, key, common.BytesToHash(modifiedByteEncoded))

    // StateObject.CommitTrie(db, db)
    current_root := StateDB.IntermediateRoot(true)
    fmt.Println(common.ToHex(current_root[:]))

    root, err := StateDB.Commit(true)
    if err == nil {
        fmt.Println(root)
        fmt.Println(common.ToHex(root[:]))
    }

    // hash2 := StateDB.GetHash()
    // fmt.Println(hash2)
    // fmt.Println(common.ToHex(hash2[:]))

     (2) Change Block
    tamperBlock.HeaderReal().Root.Set(root)
    // //tamperBlock.TxHash()
    // //tamperBlock.UncleHash()
    // //tamperBlock.ReceiptHash()
    aa := tamperBlock.Root()
    bb := tamperBlock.Hash()

    fmt.Println(common.ToHex(aa[:]))
    fmt.Println(common.ToHex(bb[:]))

     (3) Set the TotalDifficulty

    tdOriginal := big.NewInt(1456846644) // totalDfficulty from eth.getBlock()
    TD := new(big.Int).Add(tdOriginal, tamperBlock.Difficulty())

     (4) Delete the current Block
    core.DeleteBlock(db, currentBlockHash, currentBlockNumber)
    core.DeleteCanonicalHash(db, currentBlockNumber)
    core.DeleteTransaction(db, currentBlockHash)

     (5) Add the tampered Block
    if err := core.WriteBlock(db, tamperBlock); err != nil {
        fmt.Println("failed to insert block number: %v", err)
    }
    if err := core.WriteCanonicalHash(db, tamperBlock.Hash(), tamperBlock.NumberU64()); err != nil {
        fmt.Println("failed to store number to hash mapping into database: %v", err)
    }
    // WriteTd is important. If you want to successfully hack, totalDifficulty should be large than that of the correct block.
    if err := core.WriteTd(db, tamperBlock.Hash(), tamperBlock.NumberU64(), TD); err != nil {
        fmt.Println("failed to store block total difficulty into database: %v", err)
    }
    if err := core.WriteHeadBlockHash(db, tamperBlock.Hash()); err != nil {
        fmt.Println("failed to store last header's hash into database: %v", err)
    }
    if err := core.WriteHeadHeaderHash(db, tamperBlock.Hash()); err != nil {
        fmt.Println("failed to store last block's hash into database: %v", err)
    }
    if err := core.WriteHeadFastBlockHash(db, tamperBlock.Hash()); err != nil {
        fmt.Println("failed to store last fast block's hash into database: %v", err)
    }
    if err := core.WriteBlockReceipts(db, tamperBlock.Hash(), tamperBlock.NumberU64(), currentReceipts); err != nil {
        fmt.Println("error writing block receipts:", err)
    }
    if err := core.WriteTransactions(db, tamperBlock); err != nil {
        fmt.Println("failed to store transactions into database:", err)
    }

     (5) Check
    currentTamperBlockHash := core.GetHeadBlockHash(db)
    currentTamperBlock := core.GetBlock(db, currentTamperBlockHash, currentBlockNumber)
    a := currentTamperBlock.Root()
    b := currentTamperBlock.Hash()
    fmt.Println(common.ToHex(a[:]))
    fmt.Println(common.ToHex(b[:]))

}
在拷贝的源码里
core/types/block.go453行Hash(),comment out了第一个判断,并且395行加上了func (b *Block) HeaderReal() *Header { return b.header }

core/state/state_object.go最后添加
func (self *StateObject) ForEachStorage2() {
    // When iterating over the storage check the cache first
    //for h, value := range self.cachedStorage {
    //  cb(h, value)
    //}
    // test := []byte{160, 123, 34, 68, 97, 116, 101, 34, 58, 32, 34, 50, 48, 49, 55, 45, 48, 54, 45, 49, 51, 32, 50, 49, 58, 51, 56, 58, 52, 52, 34, 44, 32}
    it := self.getTrie(self.db.db).Iterator()
    for it.Next() {
        // ignore cached values
        var decodedValue []byte
        key := self.trie.GetKey(it.Key)
        keyHex := common.ToHex(key)
        rlp.DecodeBytes(it.Value, &decodedValue)
        values := common.ToHex(decodedValue)
        valueAscII, err := hex.DecodeString(values[2:])
        if err != nil {
            panic(err)
        }

        // key2 := it.Key
        fmt.Println("Hashkey sent to SetState(): ", common.BytesToHash(key))
        fmt.Println("keyByte: ", key)
        fmt.Println("itKey: ", it.Key)
        // fmt.Println("hashKey: ", self.trie.HashKeyTest(test))   //This result is exactly the it.Key
        fmt.Println("keyHex: ", keyHex)
        fmt.Println("valueByteRLPEncoded: ", it.Value)
        fmt.Println("HashValue sent to SetState(), which is the valueRLPdecodedByte: ", decodedValue) // The same as common.BytesToHash(it.Value)
        fmt.Println("valueRLPdecodedHex: ", values)
        fmt.Println("valueAscII: ", string(valueAscII), "\n")

        // self.GetState(self.db.db, key)
        //if _, ok := self.cachedStorage[key]; !ok {
        //  cb(key, common.BytesToHash(it.Value))
        //}
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值