├── README.md ├── proofOfWork.py ├── blockChain.py └── .gitignore /README.md: -------------------------------------------------------------------------------- 1 | # BlockChain -------------------------------------------------------------------------------- /proofOfWork.py: -------------------------------------------------------------------------------- 1 | import hashlib 2 | import requests 3 | 4 | 5 | sha256 = hashlib.sha256() 6 | sha256.update('heroyf1'.encode('utf-8')) 7 | res1 = sha256.hexdigest() 8 | 9 | # sha256.update('heroyf2'.encode('utf-8')) 10 | # res2 = sha256.hexdigest() 11 | # print(res1 ,res2) 12 | 13 | 14 | def proofOfWork(): 15 | data = 'heroyf' 16 | x = '1' 17 | sha256.update((data+x).encode('utf-8')) 18 | while True: 19 | if str(sha256.hexdigest())[0:1] != "0": 20 | x = str(int(x) + 1) 21 | else: 22 | print(str(sha256.hexdigest())) 23 | print(x) 24 | break 25 | 26 | 27 | proofOfWork() 28 | -------------------------------------------------------------------------------- /blockChain.py: -------------------------------------------------------------------------------- 1 | import hashlib 2 | 3 | def sha256(dataNeedSha): 4 | sha256 = hashlib.sha256() 5 | sha256.update(dataNeedSha.encode('utf-8')) 6 | return sha256.hexdigest() 7 | 8 | # 区块 9 | class Block: 10 | def __init__(self, data, previousHash): 11 | self.data = data 12 | self.previousHash = previousHash 13 | self.hash = self.ComputeHash 14 | 15 | @property 16 | def ComputeHash(self): 17 | return str(sha256(self.data)) 18 | 19 | def showBlock(self): 20 | print ({'data':self.data, 'previousHash': self.previousHash, 'hash': self.hash}) 21 | 22 | 23 | # 链 24 | class Chain: 25 | def __init__(self): 26 | self.chain = [self.ancestorBlock] 27 | 28 | @property 29 | def ancestorBlock(self): 30 | ancestor_block = Block('祖先区块', '') 31 | return ancestor_block 32 | 33 | @property 34 | def getLatestBlock(self): 35 | return self.chain[len(self.chain) - 1] 36 | 37 | def addBlockToChain(self, newBlock): 38 | newBlock.previousHash = self.getLatestBlock.hash 39 | newBlock.hash = newBlock.ComputeHash 40 | self.chain.append(newBlock) 41 | 42 | def showChain(self): 43 | for i in self.chain: 44 | i.showBlock() 45 | 46 | def validateChain(self): 47 | if len(self.chain) == 1: 48 | if self.chain[0].hash != self.chain[0].ComputeHash: 49 | return False 50 | return True 51 | 52 | for i in range(1,len(self.chain)): 53 | blockToValidate = self.chain[i] 54 | if (blockToValidate.hash) != blockToValidate.ComputeHash: 55 | print('数据被篡改') 56 | return False 57 | previousBlock = self.chain[i-1] 58 | if blockToValidate.previousHash != previousBlock.hash: 59 | print('前后区块链接断裂') 60 | return False 61 | return True 62 | 63 | block1 = Block('转账10', '') 64 | block2 = Block('转账20', '') 65 | bitChain = Chain() 66 | bitChain.addBlockToChain(block1) 67 | bitChain.addBlockToChain(block2) 68 | 69 | 70 | # 尝试篡改区块 71 | bitChain.chain[1].data = '转账500' 72 | # 尝试修正hash 73 | bitChain.chain[1].hash = bitChain.chain[1].ComputeHash 74 | bitChain.showChain() 75 | print(bitChain.validateChain()) 76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | .vscode/ 4 | *.py[cod] 5 | *$py.class 6 | 7 | # C extensions 8 | *.so 9 | 10 | # Distribution / packaging 11 | .Python 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | wheels/ 24 | pip-wheel-metadata/ 25 | share/python-wheels/ 26 | *.egg-info/ 27 | .installed.cfg 28 | *.egg 29 | MANIFEST 30 | 31 | # PyInstaller 32 | # Usually these files are written by a python script from a template 33 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 34 | *.manifest 35 | *.spec 36 | 37 | # Installer logs 38 | pip-log.txt 39 | pip-delete-this-directory.txt 40 | 41 | # Unit test / coverage reports 42 | htmlcov/ 43 | .tox/ 44 | .nox/ 45 | .coverage 46 | .coverage.* 47 | .cache 48 | nosetests.xml 49 | coverage.xml 50 | *.cover 51 | *.py,cover 52 | .hypothesis/ 53 | .pytest_cache/ 54 | 55 | # Translations 56 | *.mo 57 | *.pot 58 | 59 | # Django stuff: 60 | *.log 61 | local_settings.py 62 | db.sqlite3 63 | db.sqlite3-journal 64 | 65 | # Flask stuff: 66 | instance/ 67 | .webassets-cache 68 | 69 | # Scrapy stuff: 70 | .scrapy 71 | 72 | # Sphinx documentation 73 | docs/_build/ 74 | 75 | # PyBuilder 76 | target/ 77 | 78 | # Jupyter Notebook 79 | .ipynb_checkpoints 80 | 81 | # IPython 82 | profile_default/ 83 | ipython_config.py 84 | 85 | # pyenv 86 | .python-version 87 | 88 | # pipenv 89 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 90 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 91 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 92 | # install all needed dependencies. 93 | #Pipfile.lock 94 | 95 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 96 | __pypackages__/ 97 | 98 | # Celery stuff 99 | celerybeat-schedule 100 | celerybeat.pid 101 | 102 | # SageMath parsed files 103 | *.sage.py 104 | 105 | # Environments 106 | .env 107 | .venv 108 | env/ 109 | venv/ 110 | ENV/ 111 | env.bak/ 112 | venv.bak/ 113 | 114 | # Spyder project settings 115 | .spyderproject 116 | .spyproject 117 | 118 | # Rope project settings 119 | .ropeproject 120 | 121 | # mkdocs documentation 122 | /site 123 | 124 | # mypy 125 | .mypy_cache/ 126 | .dmypy.json 127 | dmypy.json 128 | 129 | # Pyre type checker 130 | .pyre/ 131 | --------------------------------------------------------------------------------