[Ethereum] Ubuntuでmining

まず、Minergateに登録する
https://minergate.com/reg

$ sudo apt-get update
$ sudo apt-get install software-properties-common
$ sudo add-apt-repository -y ppa:ethereum/ethereum-qt
$ sudo add-apt-repository ppa:ethereum/ethereum
$ sudo add-apt-repository ppa:ethereum/ethereum-dev
$ sudo apt-get update
$ sudo apt-get install ethminer
$ sudo apt-get install ethminer
Reading package lists… Done
Building dependency tree
Reading state information… Done
E: Unable to locate package ethminer
これだと上手くいかない

$ sudo apt install nvidia-cuda-toolkit
$ nvcc -V
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2019 NVIDIA Corporation
Built on Sun_Jul_28_19:07:16_PDT_2019
Cuda compilation tools, release 10.1, V10.1.243

$ mkdir ethminer
$ wget -O ethminer/ethminer.tar.gz https://github.com/ethereum-mining/ethminer/releases/download/v0.18.0/ethminer-0.18.0-cuda-9-linux-x86_64.tar.gz
$ tar xzf ethminer/ethminer.tar.gz -C ethminer/
$ ethminer/bin/ethminer –help
$ ethminer/bin/ethminer -U -P stratum+tcp://eth.pool.minergate.com:45791/*@gmail.com

なるほど 手順はわかった
あとはsolidityの基礎とreact, truffle周りかな

[Ethereum] ERC721トークン

ERC721は、スマートコントラクト内でNon-Fungible Tokenを扱えるようにしたもの

pragma solidity ^0.4.23;

import "github.com/OpenZeppelin/openzeppelin-solidity/contracts/token/ERC721/ERC721Full.sol";
import "github.com/OpenZeppelin/openzeppelin-solidity/contracts/token/ERC721/ERC721Mintable.sol";
import "github.com/OpenZeppelin/openzeppelin-solidity/contracts/ownership/Ownable.sol";

contract MyTokenCollection is ERC721Full, ERC721Mintable, Ownable {
	
	constructor() public ERC721Full("MyTokenCollection", "MTC"){}

	function mintTokenCollection(string _tokenURI) public {
		uint256 newTokenId = _getNextTokenId();
		_mint(msg.sender, newTokeId);
		_setTokenURI(newTokenId, _tokenURI);
	}

	function _getNextTokenId() private view returns(uint256){
		return totalSupply().add(1);
	}
}

なるほど、Truffleもう一回ちょっとやり直す必要があるかな
Reactの勉強もしないといけないか…

[Ethereum] Reactでdappを作りたい

$ sudo npm install -g create-react-app
$ create-react-app lottery-react
$ cd lottery-react
$ npm run start

http://192.168.34.10:3000/

$ sudo npm install -g yarn
$ yarn -v
1.22.5
$ npm install –save web3@1.0.0-beta.26

$ cd ..
$ mkdir lottery
$ cd lottery
$ sudo npm install solc@0.4.17
$ npm install –save mocha ganache-cli web3@1.0.0-beta.26
$ npm install –save truffle-hdwallet-provider@0.0.3

contract/Lottery.sol

pragma solidity ^0.4.17;

contract Lottery {
	address public manager;
	address[] public players;

	function Lottery () public {
		manager = msg.sender;
	}

	function enter() public payable {
		require(msg.value > .01 ether);

		players.push(msg.sender);
	}

	function random() private view return (uint) {
		return uint(keccak256(block.difficulty, now, players));
	}

	function pickWinner() public restricted {
		uint index = random() % players.length;
		players[index].transfer(this.balance);
		players = new address[](0);
	}

	modifier restricted() {
		require(msg.sender == manager);
		_;
	}

	function getPlayers() public view returns(address[]){
		return players;
	}
}

compiler.js

const path = require('path');
const fs = require('fs');
const solc = require('solc');

const IndexPath = path.resolve(__dirname,'contracts', 'Lottery.sol');
const source = fs.readFileSync(IndexPath, 'utf8');

console.log(solc.compile(source,1));

ABIとは、Application Binary Interface

lottery.js

import web3 from './web3';

const address = '0xaC24CD668b4A6d2935b09596F1558c1E305F62F1';


const abi = [{
    "constant": true,
    "inputs": [],
    "name": "manager",
    "outputs": [{
        "name": "",
        "type": "address"
    }],
    "payable": false,
    "stateMutability": "view",
    "type": "function"
}, {
    "constant": false,
    "inputs": [],
    "name": "pickWinner",
    "outputs": [],
    "payable": false,
    "stateMutability": "nonpayable",
    "type": "function"
}, {
    "constant": true,
    "inputs": [],
    "name": "getPlayers",
    "outputs": [{
        "name": "",
        "type": "address[]"
    }],
    "payable": false,
    "stateMutability": "view",
    "type": "function"
}, {
    "constant": false,
    "inputs": [],
    "name": "enter",
    "outputs": [],
    "payable": true,
    "stateMutability": "payable",
    "type": "function"
}, {
    "constant": true,
    "inputs": [{
        "name": "",
        "type": "uint256"
    }],
    "name": "players",
    "outputs": [{
        "name": "",
        "type": "address"
    }],
    "payable": false,
    "stateMutability": "view",
    "type": "function"
}, {
    "inputs": [],
    "payable": false,
    "stateMutability": "nonpayable",
    "type": "constructor"
}];


export default new web3.eth.Contract(abi, address);

web3.js

import Web3 from 'web3';

const web3 = new Web3(window.web3.currentProvider);

export default web3;

App.js

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import web3 from './web3';
import lottery from './lottery';

class App extends Component {
  state = {
    manager: '',
    player: [],
    balance: '',
    value: '',
    messaget: ''
  };

  async componentDidMount() {
    const manager = await lottery.methods.manager().call();
    const players = await lottery.methods.getPlayers().call();
    const balance = await web3.eth.getBalance(lottery.opetions.address);

    this.setState({manager, players, balance});
  }

  onSubmit = async(event) => {
    event.preventDefault();

    const accounts = await web3.eth.getAccounts();

    this.setState({message: 'Waiting on transaction success...'});

    await lottery.methods.enter().send({
      from: accounts[0],
      value: web3.utils.toWei(this.state.value, 'ether')
    });

    this.setState({message: 'you have been entered!'});
  };

  onClick = async() => {
    const accounts = await web3.eth.getAccounts();

    this.setState({message: "waiting on transaction success..."});

    await lottery.methods.pickWinner().send({
      from: accounts[0]
    });

    this.setState({message: 'A winner has been picked'});
  };

  render() {
    return (
    <div>
      <h2>Lottery Contract</h2>
      <p>
        This contract is managed by {this.state.manager}.
        There are currently {this.state.players.length} peple entered,
        competing to win {web3.utils.fromWei(this.state.balance, 'ether')}
      </p>
      <hr />

        <form onSubmit={this.onSubmit}>
            <h4>Want to try your luck?</h4>
            <div>
              <label>Amount of ether to enter</label>
              <input
              value = {this.state.value}
                onChange={event => this.setState({ value: event.target.value })}
              />
            </div>
            <button>Enter</button>
        </form>

        <hr />

        <h4>Ready to pick a winner?</h4>
        <button onClick={this.onClick}>Pick a winner!</button>

        <hr />
        <h1>{this.state.message}</h1>
      </div>
  );
  }
}

export default App;

なるほど、全体の流れはわかった

[Ethereum] wallet address, mnemonicの作成

Ethereum uses ECDSA to generate public-private key pairs as Bitcoin does.
Ethereum address is generated by hashing public key with keccak256, slicing last 20 bytes, and adding “0x” at the top.

privateKey -> derive with ECDSA -> publicKey -> hash -> Ethereum address

const Web3 = require("web3");

const mnemonic = "*";

const HDWalletProvider = require('truffle-hdwallet-provider');
let provider = new HDWalletProvider(mnemonic, 'https://ropsten.infura.io/v3/*', 0, 1);

let web3 = new Web3(provider);

let account = web3.eth.accounts.create();

console.log("address:" + account.address);
console.log("privateKey:" + account.privateKey);

$ node address.js
address:0xefC5B5d9A4BDA3bE4f4da8e7AaFe25F08C5EAce7
privateKey:********
$ node address.js
address:0xB19C2356a88F5437e253d404DA642EC914dCC794
privateKey:********

ニーモニック(mnemonic)はあるだけで口座管理ができる
キーストアはパスワードがないと何も出来ない
MetaMaskのウォレットではmnemonicから秘密鍵を作る仕組みがある

### mnemonic
12ワードは128bitのエントロピーから生成される(randomな値)
エントロピーからチェックサムを生成し足し合わせバイト列に変換し11bit(最大2048)ごとに分割
分割した値をindex値としてワードリストの索引
PBKDF2-SHA512から生成 2048回ストレッチ

なるほど、中々凄いことになってるわ

[Bitcoin] Walletの概要

秘密鍵 => 公開鍵 => ビットコインウォレットの順番で作られる。
OpenSSLで秘密鍵、公開鍵を作る手順と一緒
ウォレットは、「秘密鍵」「公開鍵」を保持し、管理する

### ウォレットの鍵の管理手法
ランダムウォレット と HDウォレットがある

– ランダムウォレット
秘密鍵公開鍵を1:1の関係で生成し管理する
ただし、複数の秘密鍵を管理保持しなければならない

– HDウォレット(Hierarchy Deterministic)
シードと呼ばれる値から秘密鍵を生成し、階層構造を用いて管理する
シードがあれば、秘密鍵は複数管理する必要はない(管理コストが下がる)

乱数生成器 -> シード -> HMAC-SHA512 -> 親秘密鍵(256bit) + 親ChainCode(256bit) *子秘密鍵生成に使用

親秘密鍵 + 親ChainCode + index -> HMAC-SHA512 -> 子秘密鍵 + 子ChainCode

### パスフレーズ, BIP32, BIP44
パスフレーズとは、どの階層にどの鍵が存在するのかを一意に表したものでスラッシュ区切りで表現
BIP32の標準規格: m/a’/c/i
BIP44の標準規格: m / purpose’ / coin_type’ / account’ / change /

### HMAC-sha512
HMACは、暗号ハッシュ関数を使用して、メッセージ認証を行う仕組み

import hmac
import hashlib
key="asdf"
text="public text"
signature = hmac.new(bytearray(key, "ASCII"),bytearray(text, "ASCII"), hashlib.sha512).hexdigest()
print(signature)

$ python3 wallet.py
b83ed32cab16c05e43f0922cf5123f04d2278d4fa50e4b1edab5f0ce04e74d5900b91dec501efd96de4721313f56533b55c1fec837b92bebe6126df7838dcc6d

### bitcoinのlibraryを使う場合

from bitcoin import *
my_private_key = random_key()
print(my_private_key)
public_key = privtopub(my_private_key)
print(public_key)
wallet_address = pubtoaddr(public_key)
print(wallet_address)

秘密鍵 => 公開鍵 => ビットコインウォレットの順番で作る

$ python3 wallet.py
336a4393ccef96b9eedb78deff766a6289d6e47983b35ee58860dd65c1a8fb86
04ef2a745e5853cea83031dd5a49de1716642ae55b1d537d2407f52757580071d7475b61b4efa2fa355d50251a286850a8548f808440c8e3739aa8bf31660dfab3
1FegPWcNYxpVMRg8rT8NhWXkzWAuk6WX2A

ああああああああああ
もうやだあ

[Ethereum] contractのdeploy その2

sample_greeting.sol

contract SampleGreeting {
	string greeting = 'Hello World';

	function getGreet() public view returns (string memory){
		return greeting;
	}
}

$ sudo snap install solc
$ solc –bin –abi sample_greeting.sol
sample_greeting.sol:1:1: Warning: Source file does not specify required compiler version! Consider adding “pragma solidity ^0.5.16;”
contract SampleGreeting {
^ (Relevant source part starts here and spans across multiple lines).

======= sample_greeting.sol:SampleGreeting =======
Binary:
60806040526040518060400160405280600b81526020017f48656c6c6f20576f726c640000000000000000000000000000000000000000008152506000908051906020019061004f929190610062565b5034801561005c57600080fd5b50610107565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100a357805160ff19168380011785556100d1565b828001600101855582156100d1579182015b828111156100d05782518255916020019190600101906100b5565b5b5090506100de91906100e2565b5090565b61010491905b808211156101005760008160009055506001016100e8565b5090565b90565b61018a806101166000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063d705a4b514610030575b600080fd5b6100386100b3565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561007857808201518184015260208101905061005d565b50505050905090810190601f1680156100a55780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b606060008054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561014b5780601f106101205761010080835404028352916020019161014b565b820191906000526020600020905b81548152906001019060200180831161012e57829003601f168201915b505050505090509056fea265627a7a72315820be61e923cb4240e17bacc0ab36f4b2a0e91dd3c77c284e3edcc3bbcbc6e5079564736f6c63430005100032
Contract JSON ABI
[{“constant”:true,”inputs”:[],”name”:”getGreet”,”outputs”:[{“internalType”:”string”,”name”:””,”type”:”string”}],”payable”:false,”stateMutability”:”view”,”type”:”function”}]

const Web3 = require('web3');

const mnemonic = "*";

const HDWalletProvider = require('truffle-hdwallet-provider');
let provider = new HDWalletProvider(mnemonic, 'https://ropsten.infura.io/v3/*', 0, 1);

let web3 = new Web3(provider);

let bin = '0x60806040526040518060400160405280600b81526020017f48656c6c6f20576f726c640000000000000000000000000000000000000000008152506000908051906020019061004f929190610062565b5034801561005c57600080fd5b50610107565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100a357805160ff19168380011785556100d1565b828001600101855582156100d1579182015b828111156100d05782518255916020019190600101906100b5565b5b5090506100de91906100e2565b5090565b61010491905b808211156101005760008160009055506001016100e8565b5090565b90565b61018a806101166000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063d705a4b514610030575b600080fd5b6100386100b3565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561007857808201518184015260208101905061005d565b50505050905090810190601f1680156100a55780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b606060008054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561014b5780601f106101205761010080835404028352916020019161014b565b820191906000526020600020905b81548152906001019060200180831161012e57829003601f168201915b505050505090509056fea265627a7a72315820be61e923cb4240e17bacc0ab36f4b2a0e91dd3c77c284e3edcc3bbcbc6e5079564736f6c63430005100032';
let abi = [{"constant":true,"inputs":[],"name":"getGreet","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"}];
let data = {
	'data': bin
}

let contract = new web3.eth.Contract(abi, null, data);
console.log('contract:', contract);

$ node sample.js
///
_jsonInterface:
[ { constant: true,
inputs: [],
name: ‘getGreet’,
outputs: [Array],
payable: false,
stateMutability: ‘view’,
type: ‘function’,
signature: ‘*’ } ] }

signatureの値をメモしておく

web3.eth.getGasPrice().
	then((averageGasPrice) => {
		console.log("gasPrice: " + averageGasPrice);
	}).catch(console.error);

web3.eth.getAccounts((error, result) => {
	console.log('result: ', result);

	web3.eth.getTransactionCount(result[0], (error, response)=>{
		console.log('nonce:', response);
	})
})

contract.deploy().estimateGas().
	then((estimatedGas) => {
		console.log("gas: " + estimatedGas);
	}).catch(console.error);

$ node sample.js
result: [ ‘*’ ]
gasPrice: 1500000013
gas: 164431
nonce: 3

let sender_address = "*";
let nonce = '3';
let chainId = '3';
let gas = 164431;
let gasPrice = '1500000013'

let tx = {
  'from': sender_address,
  'nonce': nonce,
  'chainId': chainId,
  'gas': gas,
  'gasPrice': gasPrice,
  'data': bin,
}

const PRIVATE_KEY = "*";

web3.eth.accounts.signTransaction(tx, PRIVATE_KEY, (error, response)=>{
    console.log(response);
});

{ messageHash:
‘0x71d7*’,
v: ‘0x2a’,
r:
‘0xd04f9c44192de22c1088feccc*’,
s:
‘0x593a5ec5a50d1d5bed367*’,
rawTransaction:
‘0xf902f2038459682f0d8302824f8080b902a060806040526040518060400160405280600b81526020017f48656c6c6f20576f726c640000000000000000000000000000000000000000008152506000908051906020019061004f929190610062565b5034801561005c57600080fd5b50610107565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100a357805160ff19168380011785556100d1565b828001600101855582156100d1579182015b828111156100d05782518255916020019190600101906100b5565b5b5090506100de91906100e2565b5090565b61010491905b808211156101005760008160009055506001016100e8565b5090565b90565b61018a806101166000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063d705a4b514610030575b600080fd5b6100386100b3565b604051808060200182810*’,
transactionHash:
‘0x55a06ab424128b04b9002fe7de1a17e8981d94728bac06dd55993cfdba1b860d’ }

デプロイ

let raw = '0xf902f2038459682f0d8302824f8080b902a060806040526040518060400160405280600b81526020017f48656c6c6f20576f726c640000000000000000000000000000000000000000008152506000908051906020019061004f929190610062565b5034801561005c57600080fd5b50610107565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100a357805160ff19168380011785556100d1565b828001600101855582156100d1579182015b828111156100d05782518255916020019190600101906100b5565b5b5090506100de91906100e2565b5090565b61010491905b808211156101005760008160009055506001016100e8565b5090565b90565b61018a806101166000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063d705a4b514610030575b600080fd5b6100386100b3565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561007857808201518184015260208101905061005d565b50505050905090810190601f1680156100a5578082038051600183*';

web3.eth.sendSignedTransaction(raw).on('receipt', console.log);

$ node sample.js
{ blockHash:
‘0x8414d2fac3b36315828b7d330287a181e3b58ac29ee5d1325fb27b6d92dc03d1’,
blockNumber: 11682111,
contractAddress: ‘0x31695391C6C0f3A3F2EDe7cDb9B13Da277A8e2Eb’,
cumulativeGasUsed: 1680291,
effectiveGasPrice: ‘0x59682f0d’,
from: ‘0x71c9f1d5be00173ae7b774bdbe2112cdd03c5c92’,
gasUsed: 164431,
logs: [],
logsBloom:
‘0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000’,
status: true,
to: null,
transactionHash:
‘0x55a06ab424128b04b9002fe7de1a17e8981d94728bac06dd55993cfdba1b860d’,
transactionIndex: 13,
type: ‘0x0’ }

web3.eth.getAccounts((error, result)=> {
	let sender_address = result[0]
	let call_data = {
		'from': sender_address,
		'to': recipient_address,
		'data': signature
	}

	web3.eth.call(call_data, (error, response) => {
		console.log('response: ', response);
		provider.engine.stop();
	})
})

$ node sample.js
response: 0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000b48656c6c6f20576f726c64000000000000000000000000000000000000000000

おおおお なるほど
solidityでcompileしたデータを、from, nonce, chainId, gas, gasPriceなどと一緒にトランザクションにして秘密鍵で署名してデプロイしてるのね。

一連の流れはわかった!

[Ethereum] シンプルなスマートコントラクトをデプロイ

$ mkdir rinkeby
$ cd rinkeby
$ npm init

{
  "name": "inbox",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}

solidityのcompilerをinstall
$ npm install –save solc

mocha(テストフレーム)をinstall
$ npm install –save mocha ganache-cli web3@1.0.0-beta.26

truffle-hdwallet-providerをインストール
$ npm install –save truffle-hdwallet-provider@0.0.3

const path = require('path');
const fs = require('fs');
const solc = require('solc');

const inboxPath = path.resolve(__dirname, 'contracts', 'Inbox.sol');
const source = fs.readFileSync(inboxPath, 'utf8');

moudle.exports = solc.compile(source,1).contracts[':Inbox'];

Inbox.sol

pragma solidity ^0.8.11;

contract Inbox {
	string public message;

	function Inbox(string initialMessage) public {
		message = initialMessage;
	}

	function setMessage(string newMessage) public {
		message = newMessage;
	}
}

deploy.js

const HDWalletProvider = require('truffle-hdwallet-provider');
const Web3 = require('web3');
const { interface, bytecode } = require('./compile');

const provider = new HDWalletProvider (
	'harmonic',
	'https://ropsten.infura.io/v3/*'
);

const web3 = new Web3(provider);

const deploy = async () => {

	const accounts = await web3.eth.getAccounts();

	console.log('Attempting to deploy from account', accounts[0]);

	const result = await new web3.eth.Contract(JSON.parse(interface))
		.deploy({data: bytecode, arguments:['Hi there!']})
		.send({gas:'1000000', from: accounts:[0]});

	console.log('Contract deploy to', result.options.address);
}

$ node deploy.js
Attempting to deploy from account *
(node:408216) UnhandledPromiseRejectionWarning: Error: intrinsic gas too low

うーむ、gasの設定の方法がよくわかん
gasの概念の理解が先か…

[話者認識] i-vectorとは

GMMスーパーベクトルは、時系列データである発話をベクトル空間上の一点として表現するもの
i-vectorもこのGMMスーパーベクトルを基礎としている
識別モデルアプリーチから因子分析アプローチに転換している
話者以外の要因を緻密にモデル化し除去し用としても限界があった
話者とチャンネル因子xの空間にGMMスーパーベクトルを写像する因子分析モデルを提案した。この写像がi-vector 全因子wの事後分布の平均値E[w]として得られる

### i-vectorによる話者照合
1.登録話者i-vector w1と照合話者のi-vector w2のコサイン類似度によりスコアリングを行う
SVM同等以上の性能
2. i-vector w1, w2を用いて、同一モデルから生成されたか否かの仮説を評価

### sidekit
$ mkdir i-vector
$ cd i-vector
$ pip3 install sidekit

import sidekit

fa = sidekit.FactoryAnalyser()

fa.total_variability_single(stat_server_filename,
	ubm,
	tv_rank,
	nb_iter=20,
	min_div=True,
	tv_init=None,
	batch_size=300,
	save_init=False,
	output_file_name=None)

$ python3 main.py
Traceback (most recent call last):
File “main.py”, line 3, in
fa = sidekit.FactoryAnalyser()
AttributeError: module ‘sidekit’ has no attribute ‘FactoryAnalyser’

あれ、何かがおかしい

[Ethereum] じゃんけんゲームをして勝ったらEthereumを貰える

Rapstonだと、送金処理ができなかったので、private netに接続します。
勝った時のみ、Etherの送金処理を実行します。

<div class="container">
	<h1>Ethereum</h1>
	<div id="balanceArea"></div>
	<br><br>
	<h1>じゃんけん</h1>
	<button onclick="R_Click(0)">グー</button>
	<button onclick="R_Click(1)">チョキ</button>
	<button onclick="R_Click(2)">パー</button>
	<br><br>
	<div id="area1"></div>
	<div id="area2"></div>
	</div>
	<script>
		let balanceArea = document.getElementById('balanceArea');
		const web3 = new Web3();
		const userWallet = "";
		const adminWallet = "";
		web3.setProvider(new web3.providers.HttpProvider('http://192.168.33.10:8545'));

		function R_Click(p_janken_r){
			let janken = ["グー","チョキ","パー"];
			let janken_r = Math.floor(Math.random()*3);

			let p_janken = ["グー","チョキ","パー"];

       if (janken_r === p_janken_r) {
				Result_end = "あいこです";
			} else if(p_janken_r === 0 && janken_r === 1) {
				Result_end = "あなたの【勝ち】"; 
				win();
			} else if(p_janken_r === 1 && janken_r === 2) {
				Result_end = "あなたの【勝ち】"; 
				win();
			} else if(p_janken_r === 2 && janken_r === 0) {
				Result_end = "あなたの【勝ち】";
				win();
			} else {
				Result_end = "あなたの【負け】";
				lose();
			}
			document.getElementById("area1").innerHTML = p_janken[p_janken_r] +"を選択しました。ジャンケンの結果は・・・?<br><br>";
            document.getElementById("area2").innerHTML = "相手は" + janken[janken_r] + "! "+ Result_end;
		}
		
		main();

		async function main(){
			web3.eth.getBalance(adminWallet).then((result, error) => {
				const balance = web3.utils.fromWei(result, 'ether');
				console.log(balance);
				balanceArea.innerHTML = balance + " eth";
			});
		}

		async function win(){
			console.log("win");
			var balance = web3.eth.sendTransaction({from: userWallet, to:adminWallet, value:200});
			console.log(balance);
			main();
		}

		async function lose(){
			main();
		}
		
	</script>

トランザクションが生成されてブロックで承認されないと送金処理は実行されないので、じゃんけんに勝っても直ぐにはbalanceに反映されない。

なるほど、理解が深まった。

[Ethereum] Web3.jsでMainnetやRopsten Networkに接続する方法

infura.ioで新規にprojectを作成する
https://infura.io/dashboard

projectのendpointをメモする

メモしたendpointに接続する

<script src="https://cdnjs.cloudflare.com/ajax/libs/web3/1.7.0-rc.0/web3.min.js"></script>
	<script>
		var web3 = new Web3();
		web3.setProvider(new web3.providers.HttpProvider('https://mainnet.infura.io/v3/*'));
		var _balance = web3.eth.getBalance("${wallet address}");
		console.log(_balance)
	</script>

なるほどー 殆ど謎が解けた