Говоря о блокчейне

JavaScript блокчейн
Говоря о блокчейне

В последнее время технология блокчейн часто появляется в заголовках различных новостных приложений, и в этом случае я начал изучать технологию блокчейн.

Введение концепции

В технологии блокчейна появляется много новых концепций, и это довольно недружелюбно для тех, кто новичок в сфере блокчейна.Долгое время я не понимал, что такое блокчейн.Виртуальный кошелек - это что, зачем у транзакций есть плата за газ и т. д., поэтому в этой статье сначала будут даны некоторые концептуальные пояснения для удобства последующего обсуждения.

блокчейн

Блокчейн на самом деле представляет собой структуру связанного списка.Элементом связанного списка является блок.Структура каждого блока следующая:

  • timestamp: временная метка генерации блока
  • одноразовый номер: вместе с хэш-значением заголовка блока для подтверждения объема вычислений (рабочей нагрузки)
  • data: данные, хранящиеся в блокчейне
  • prevHash: хэш предыдущего блока
  • hash: Хэш этого блокчейна получается путем хеширования вышеуказанных свойств.

Блокчейн, по сути, представляет собой распределенный реестр транзакций, и все пользователи имеют полную информацию о реестре локально. Если пользователь хочет изменить информацию определенного блока, потому что в процессе вычисления хэша блока в качестве параметра используется prevHash, то все блоки после блока станут недействительными, и хэш необходимо будет пересчитать, чтобы система распознала это , Чтобы изменить, информация о реестре 51% пользователей должна быть изменена синхронно, поэтому очень сложно подделать информацию о реестре в блокчейне, что обеспечивает ее безопасность.

Шахтер и добыча

Майнинг — это, по сути, процесс, при котором группа узлов (майнеров) использует свои вычислительные ресурсы для создания блока, содержащего действительные транзакции.Узлы (майнеры), участвующие в этом процессе, называются майнерами. Если майнер хочет отправить блок в цепочку блоков, он должен вычислить одноразовый номер быстрее, поскольку одноразовый номер и информация из заголовка блока вместе могут доказать, что блок действителен.

доказательство работы

Как было сказано выше, в процессе майнинга майнеры должны быстрее вычислять одноразовый номер, как его вычислить? nonce представляет собой целочисленное значение. Обычно сначала добавляют строку, полученную с помощью nonce, к информации заголовка блока и выполняют хеш-операцию SHA256. Если количество нулей в начале меньше установленного значения сложности, проверка завершается неудачно, и Добавьте 1 к значению и повторяйте описанную выше операцию до тех пор, пока рассчитанный одноразовый номер не будет удовлетворять тому, что количество нулей в начале полученного хеш-значения не меньше установленного значения сложности. Значение nonce является доказательством загруженности процесса майнинга. Чтобы побудить к участию больше майнеров, система вознаградит каждого майнера, участвующего в майнинге, определенными токенами.

бумажник

Кошелек — это, по сути, файл, содержащий закрытый ключ. Обычно он содержит программный клиент, а адрес кошелька вычисляется из приватного ключа, то есть публичного ключа. Для каждой транзакции отправитель должен предоставить закрытый ключ для передачи токенов, принадлежащих адресу открытого ключа, на другие адреса открытого ключа, поэтому закрытый ключ определяет право собственности на биткойн. Здесь следует отметить, что количество токенов, принадлежащих адресу кошелька, хранится не в закрытом ключе, а в блокчейне, в блокчейне есть все исторические учетные записи транзакций, и токены, принадлежащие каждому адресу, могут быть рассчитаны в соответствии с учетными записями. , валюта.

Биткойн против Эфириума

Двумя наиболее популярными приложениями блокчейна являются система Биткойн и система Эфириум, обе из которых являются общедоступными платформами блокчейна и имеют свои собственные виртуальные валюты (Биткойн и Эфириум). Но между ними есть много отличий, одно из важных в том, что Эфириум дополняет платформу Тьюринга за счет смарт-контрактов, которые более масштабируемы в будущем, чем Биткойн. Конечно, это также связано с их собственными целями: Биткойн хочет быть чистой виртуальной валютой, а Эфириум хочет быть чистой платформой разработки, полной по Тьюрингу.

смарт-контракт

Наконец, некоторые основные концепции были популяризированы, теперь пришло время представить ключевые моменты, разработку смарт-контрактов.

Сначала познакомьтесь с инструментами, которые вам нужно использовать

geth

Geth — это официальное клиентское программное обеспечение, предоставленное Ethereum Foundation, написанное на языке программирования Go.

testrpc

Testrpc отличается от geth, geth — это среда общедоступной сети Ethereum, а testrpc — это локальная смоделированная среда Ethereum, которая удобна для тестирования и разработки.

MetaMask

MetaMask — это кошелек, разработанный на основе плагина для Chrome.

Remix

IDE для разработки смарт-контрактов, официально рекомендованная Ethereum, может быстро развертывать и тестировать смарт-контракты в браузере.

Solidity

Самый популярный язык программирования, официально запущенный Solidity для написания смарт-контрактов.

Truffle

Инструменты для составления и развертывания смарт-контрактов

Web3.js

Библиотека Javascript для взаимодействия с узлами и может использоваться для создания веб-Dapps.

Разработка смарт-контрактов

установить testrpc

npm install -g ethereumjs-testrpc # 安装 testrpc
testprc # 本地模拟以太坊环境

EthereumJS TestRPC v6.0.3 (ganache-core: 2.0.2)

Available Accounts
==================
(0) 0xca56a0e708a9b8268ea6d7b3e93728a6a324d628
(1) 0xb9b3eb735a71e0b1ae55505fa25423298c9e0ba1
(2) 0x8c0b3356fb423f2c67216627f61e2bee329ccf66
(3) 0xd67270a1a8b2bfb2045cd717307ca5475e093797
(4) 0xd2d442b9d7bb46edd53953f3c0bbae00deca9b56
(5) 0x21ef73d1bd2db40c35c169f33d04035c4fa04723
(6) 0x9a6e56ae9026abe47dd3e5b7e337d11c95e255a3
(7) 0x16e9e712af18ca96a3323aa794ce437dda348a73
(8) 0x753630b2546fdea270d380e61cbdf98b8d612f31
(9) 0x6931462530e8359cb8ff70802290065d033301e0

Private Keys
==================
(0) 0e827c0d81130b789945254cffe2d42d043ecfedc4b5b9149b9f6f8321a40a80
(1) 081824aba4f6adb70b32141600f3edf847a7bd736328104f088a1f120d5bc39b
(2) 7834de28a0d82155b56df3bf5c1e1e12d86e7de69f92850fc2b60373a25cc995
(3) 56242f1868b8da44804f07180d7d2f01ef6132e98cedd5ef9c53b9609c40cf71
(4) 955baf7ab9daa5cdbc3d1a535494f2730216f967b5d30d8db4e756376b6d6ce1
(5) b0b741a135fa5fb6011bd29c65b1dc6f72af9862630e671e85c76d43fb3db134
(6) 165db38471c04b6b87196c050f83bae2d9e6e3c14f09c61d2b7de6208ad62623
(7) c6d5523eb0f233f09d7359bb7b73f347ff1ed5efea63ca1aacd0ec52da6a8b76
(8) 0057d1448842232df2bdc5e0d8c9737dadb50aa392ad1484ec4ce592089057ba
(9) 5c574a3bd2d2c1ee4cc70bfe116b1d99dc8da107d90c116444139867f74f86c2

HD Wallet
==================
Mnemonic:      tree embark shuffle foil screen transfer struggle exotic any during stage response
Base HD Path:  m/44'/60'/0'/0/{account_index}

Listening on localhost:8545

На первую учетную запись дается 100 Ethereum, которые можно использовать для разработки и тестирования.Выберите локальную тестовую сеть на MetaMask, чтобы просмотреть баланс учетной записи.

Версия смарт-контракта hello world

pragma solidity ^0.4.14; // 定义 solidity 版本

 contract greeter {
    string greeting;

    function greeter(string _greeting) public { // 构造函数,在合约创建时执行
        greeting = _greeting;
    }

    function greet() public constant returns (string) { // 功能函数
        return greeting;
    }  
 }

Внедрить смарт-контрактную версию системы голосования

Определить типы данных роли

pragma solidity ^0.4.14; // 定义 solidity 版本

contract VoteDemo {
    struct Voter // 定义投票人
    {
      bool voted; // 是否已投票
      address addr; // 投票地址
      bytes32 voteProposalName; // 选择提案的索引
    }
    struct Proposal // 定义提案
    {
      bytes32 name; // 提案名称
      uint voteCount; // 累积得票数
    }
    address public voteCreator; // 投票发起人
    Voter[] public voters; // 所有已授权的投票人
    Proposal[] public proposals; // 所有的提案
}

Конструктор

// 创建一个提案,给出所有提案选项
function VoteDemo(bytes32[] proposalNames) public {
    for(uint i = 0; i < proposalNames.length; i++) {  // 初始化所有提案
        proposals.push(Proposal({
            name: proposalNames[i],
            voteCount: 0
        }));
    }
}
    

функция функция

// 验证提案是否合法
function checkProposalValid(bytes32 proposalName) public view returns(bool isValid) {
        isValid = false;
        for (uint i = 0; i < proposals.length; i++) {
            if (proposals[i].name == proposalName) {
                isValid = true;
            }
        }
    }
 // 获取某个提案的投票数
 function getVoteNumByProposal(bytes32 proposalName) public view returns(uint voteCount) {
       require(checkProposalValid(proposalName));
       for (uint i = 0; i < proposals.length; i++) {
           if (proposals[i].name == proposalName) {
               voteCount = proposals[i].voteCount;
           }
       }
   }
   // 获取所有提案
   function getProposalList() public view returns(Proposal[]) {
       return proposals;
   }
   // 获取投票情况
   function getVotedList() public view returns(Voter[]) {
       Voter[] memory res;
       for (uint i = 0; i < voters.length; i++) {
           if (voters[i].voted == true) {
               res[i] = Voter({
                    voted: voters[i].voted,
                    voteProposalName: voters[i].voteProposalName,
                    addr: voters[i].addr
               });
           }
       }
       return res;
   }
   // 验证投票人是否有权限参加投票
   function isValidVoter(address addr) public view returns(bool isValid) {
        isValid = false;
        for (uint i = 0; i < voters.length; i++) {
           if (voters[i].addr == addr) {
               isValid = true;
           }
       }
   }
   // 添加投票人
   function addVoter(address addr) public {
       require(msg.sender == voteCreator);
       voters.push(Voter({
           voted: false,
           addr: addr,
           voteProposalName: ''
       }));
   }
   // 投票
   function vote(bytes32 proposalName) public {
       require(isValidVoter(msg.sender));
       for (uint i = 0; i < voters.length; i++) {
           if (msg.sender == voters[i].addr) {
               voters[i].voteProposalName = proposalName;
               voters[i].voted = true;
           }
       }
   }

На данный момент написана простая версия смарт-контракта системы голосования, теперь давайте посмотрим, как ее развернуть.

Получить байт-код смарт-контракта (byte code) и бинарный интерфейс (ABI)

Скопируйте приведенный выше код смарт-контракта вremix, после компиляции получить ABI и байт-код

Создайте частную сеть

Поскольку для развертывания и запуска контрактов в публичной цепочке требуется определенное количество токенов Ethereum, вы можете создать свою собственную частную цепочку Ethereum на этапах разработки и тестирования.

Сначала скачайте и скомпилируйте geth

curl -o go-ethereum.tar.gz https://github.com/ethereum/go-ethereum/archive/v1.7.3.tar.gz
tar zxvf go-ethereum.tar.gz
cd go-ethereum
make geth
mv build/bin/geth /usr/local/bin

Создайте частную цепочку и запустите узлы

geth --identity [nodeId] --dev --datadir [datadir] --rpc --rpcaddr [yourIp] --rpcport [rpc port] --port [port]
  • --identityидентификатор пользовательского узла
  • --devрежим разработки
  • --datadirКаталог хранения данных частной цепочки
  • --rpcВключить службу RPC
  • --rpcaddrадрес службы RPC
  • --rpcportсервисный порт RPC
  • --portУкажите все номера портов для подключения к другим узлам

В это время, если вы откроете указанный каталог хранилища данных, вы найдете файл geth.ipc,

Подключиться к частной сети

Используйте geth attach для подключения к узлу приватной цепочки и откройте консоль geth.

geth attach ipc:[your ipc file]

консоль geth — это интерактивная среда JavaScript. В эту среду встроены следующие объекты для работы на Ethereum:

  • eth:Содержит методы, связанные с работой блокчейна;
  • net:Содержит методы для просмотра состояния сети p2p;
  • admin:Содержит методы, связанные с управлением узлами;
  • miner:Содержит методы для запуска и остановки майнинга;
  • personal:В основном это методы управления учетными записями;
  • txpool:Содержит методы для просмотра пулов памяти транзакций;
  • web3:Содержит указанные выше объекты, а также методы преобразования единиц измерения.

API, связанный с web3, вы можете обратиться кweb3.js - Ethereum JavaScript API.

развернуть контракт

var abi = JSON.parse(abiString) // 将前面得到的 ABI JSON 字符串转换为对象
var bytecode = 'bytecodeString'  // 前面所得到的 byte code
var contract = web3.eth.contract(abi) // 根据ABI得到智能合约
var account = web3.personal.listAccounts[0]

var instance = contract.new({
 data: bytecode, 
 gas: 1000000, 
 from: account
})

Таким образом, контракт развертывается в приватной цепочке, и теперь можно вызывать методы в контракте.

instance.xxx() // 调用合约中的方法

Суммировать

В настоящее время технологию блокчейна можно охарактеризовать как горячую.Что касается внешнего интерфейса, мы можем попытаться понять некоторые базовые знания о блокчейне и о том, как использовать web3.js для разработки внешних приложений, которые взаимодействуют с общедоступными узлами цепи. Уже есть много отличных скаффолдов, позволяющих быстро приступить к разработке фронтенд-приложений на основе смарт-контрактов Ethereum, вот несколько рекомендаций.leopoldjoy/react-ethereum-dapp-example.