[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>

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

[Ethereum] CryptoKitiies

CryptoKitties
https://www.cryptokitties.co/

ソースコード
-> contractが公開されている
https://etherscan.io/address/0x06012c8cf97bead5deae237070f9587f8e7a266d#code

contractを継承

contract KittyAccessControl
contract KittyBase is KittyAccessControl
contract KittyOwnership is KittyBase, ERC721
contract KittyBreeding is KittyOwnership
contract KittyAuction is KittyBreeding
contract KittyMinting is KittyAuction
contract KittyCore is KittyMinting
function setGeneScienceAddress(address _address) external onlyCEO {
        GeneScienceInterface candidateContract = GeneScienceInterface(_address);

        // NOTE: verify that a contract is what we expect - https://github.com/Lunyr/crowdsale-contracts/blob/cfadd15986c30521d8ba7d5b6f57b4fefcc7ac38/contracts/LunyrToken.sol#L117
        require(candidateContract.isGeneScience());

        // Set the new contract address
        geneScience = candidateContract;
    }

function giveBirth(uint256 _matronId)
        external
        whenNotPaused
        returns(uint256)
    {
        // Grab a reference to the matron in storage.
        Kitty storage matron = kitties[_matronId];

        // Check that the matron is a valid cat.
        require(matron.birthTime != 0);

        // Check that the matron is pregnant, and that its time has come!
        require(_isReadyToGiveBirth(matron));

        // Grab a reference to the sire in storage.
        uint256 sireId = matron.siringWithId;
        Kitty storage sire = kitties[sireId];

        // Determine the higher generation number of the two parents
        uint16 parentGen = matron.generation;
        if (sire.generation > matron.generation) {
            parentGen = sire.generation;
        }

        // Call the sooper-sekret gene mixing operation.
        uint256 childGenes = geneScience.mixGenes(matron.genes, sire.genes, matron.cooldownEndBlock - 1);

        // Make the new kitten!
        address owner = kittyIndexToOwner[_matronId];
        uint256 kittenId = _createKitty(_matronId, matron.siringWithId, parentGen + 1, childGenes, owner);

        // Clear the reference to sire from the matron (REQUIRED! Having siringWithId
        // set is what marks a matron as being pregnant.)
        delete matron.siringWithId;

        // Every time a kitty gives birth counter is decremented.
        pregnantKitties--;

        // Send the balance fee to the person who made birth happen.
        msg.sender.send(autoBirthFee);

        // return the new kitten's ID
        return kittenId;
    }

uint256 childGenes = geneScience.mixGenes(matron.genes, sire.genes, matron.cooldownEndBlock – 1); の mixGenesで配合している

[Blockchain] Ubuntu20.04・OpenSSLで秘密鍵公開鍵の操作

$ openssl version
OpenSSL 1.1.1f 31 Mar 2020

### 秘密鍵の作成
$ openssl ecparam -genkey -name secp256k1 -out private.pem
// ecparamは楕円曲線暗号における楕円曲線パラメータに関するサブコマンド
$ cat private.pem
—–BEGIN EC PARAMETERS—–
BgUrgQQACg==
—–END EC PARAMETERS—–
—–BEGIN EC PRIVATE KEY—–
MHQCAQEEINB5OV0K2ggkM2a0bmVTcj7FioqK5TDI9NJAxgOUjcFOoAcGBSuBBAAK
oUQDQgAELnHK99GtgUL9F3Q5YSwYa5ZdI8uY0P5diBTZZN4Ld7feo13zqYO9oQm3
G1YHB2ITeG81+KridKnVOzDk0RwA7w==
—–END EC PRIVATE KEY—–

### 公開鍵の作成
$ openssl ec -in private.pem -pubout -out public.pem
// echは楕円曲線暗号に関するサブコマンド
read EC key
writing EC key
$ cat public.pem
—–BEGIN PUBLIC KEY—–
MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAELnHK99GtgUL9F3Q5YSwYa5ZdI8uY0P5d
iBTZZN4Ld7feo13zqYO9oQm3G1YHB2ITeG81+KridKnVOzDk0RwA7w==
—–END PUBLIC KEY—–

### メッセージの作成、ハッシュ化
$ sha256sum test.txt | cut -c1-64 > hashed.txt
$ cat hashed.txt
d8aa344276524074fbfec2249bedb89a5ddccc9dc57504e92a9963f48bdf68d1

### verify
ハッシュ化した書類と秘密鍵でhashed.sigを作成し、公開鍵とhashed.sigで検証する
$ openssl dgst -SHA256 -sign private.pem hashed.txt > hashed.sig
// dgstはメッセージダイジェストを計算
$ ls
hashed.sig hashed.txt private.pem public.pem test.txt
$ openssl dgst -SHA256 -verify public.pem -signature hashed.sig hashed.txt
Verified OK

apostilleのことだね

[Ethereum] RemixとMetamask, Rapsten networkの使い方

1. ブラウザでRemixのサイトを開く
https://remix.ethereum.org/#optimize=false&runs=200&evmVersion=null&version=soljson-v0.8.7+commit.e28d00a7.js

2. 左メニューでイーサのマークをクリックし、Injected web3を選択する

3. contractを作成し、compilerを0.4.16に合わせてコンパイル

4. 1億tmcnをdeploy
100000000, “Timecoin”, “TMCN”

5. metamaskに通知が来るのでconfirm

6. deployされる

7. Etherscanでtransactionが確認できる

8. Metamaskのtoken importでcontractのhashを入力し、トークンをインポートする

9. MyEtherWalletにログイン
timecoin, tmcnが入っているのがわかる

10. tachyon walletをインストール

11. QRコードでコントラクトをQRコード化する
QRコード作成サイト
https://www.cman.jp/QRcode/qr_make/
{ERC20:0xeE19196D02D69012c4e7Ce962B528360681F8E36}

12. tachyon walletで networkをRopstenにして、新しい通貨を追加

13. MetaMaskからtachyon walletのアドレスに向けて送信

14. tachyon walletで受け取り

おおおおおおおおおおおおおおおおおお
大分概念を理解した^^
Ethを動かした方が早いですね

[Ethereum] web3.jsをhtml内で使用する

web3.jsはcdnで実装する
weiからethに変更するのも、web3.utils.fromWei(result, ‘ether’);で一発

<div class="container">
		<a href="/"><h1 class="title">My Ethereum</h1></a><br>
		<nav class="panel">
		  <p class="panel-heading">
		    Balance
		  </p>
		  <div class="box">
		    <div class="field">
				<label class="label">Ethereum Address</label>
				<div class="control">
					<input class="input" type="text" id="wallet" placeholder="wallet address">
				</div>
			</div>
		  </div>
		  
		 </nav>
		<p>Please enter the wallet address and press the button</p>
		<input type="submit" class="button is-link" id="btn" value="Check" onclick="OnButtonClick();">
		<br>
		<br>
		<br>
		
		<article class="message">
		<div class="message-header">
		    <p>Balance</p>
		  </div>
		  <div class="message-body">
		  	<div id="resArea"></div>
		    
		  </div>
		</article>
		<br>
		<a href="" target="_blank">BLOCK Chain explore</a>
	</div>
	<script src="https://cdnjs.cloudflare.com/ajax/libs/web3/1.7.0-rc.0/web3.min.js"></script>
	<script>
		let resArea = document.getElementById('resArea');
		let wallet = document.getElementById('wallet');

		function OnButtonClick() {
			main();	
			
		}
		async function main(){
			var web3 = new Web3();
			web3.setProvider(new web3.providers.HttpProvider('http://192.168.33.10:8545'));
			web3.eth.getBalance(wallet.value).then((result, error) => {
				const balance = web3.utils.fromWei(result, 'ether');
				console.log(balance);
				resArea.innerHTML = balance + " eth";
			});
			
		}
		
	</script>

なるほどー

送信する場合も同じ

<script src="https://cdnjs.cloudflare.com/ajax/libs/web3/1.7.0-rc.0/web3.min.js"></script>
	<script>
		let resArea = document.getElementById('resArea');
		let wallet = document.getElementById('wallet');
		let volume = document.getElementById('volume');

		function OnButtonClick() {
			main();	
			
		}
		async function main(){
			var web3 = new Web3();
			web3.setProvider(new web3.providers.HttpProvider('http://192.168.33.10:8545'));
			web3.eth.sendTransaction({from: "0x6752a913de4f4530ed3f071371db8d70acc42fce", to:wallet.value, value: volume.value});
			web3.eth.getBalance(wallet.value).then((result, error) => {
				console.log(result);
				resArea.innerHTML = result;
			});
			
		}
		
	</script>

自分で作ると時間かかるね

[Ethereum] 独自トークンをMetaMaskに送信

Metamaskで新規 RPC URLにhttp://192.168.33.10:8545 とする。
chainIDはgenesis.jsonの10で設定する

  "config": {
        "chainId": 10,
        "homesteadBlock": 0,
        "eip150Block": 0,
        "eip155Block": 0,
        "eip158Block": 0
    },

import tokenでbroser-solidityのコントラクトのアドレスと作成したコインを入力する

transferでmetamaskのアドレスを入力する
personal.unlockAccount(eth.accounts[0],”pass1″)
“0x71c9f1D5bE00173ae7B774bDBE2112cdD03C5C92”, 20000000

transactionが生成される

メタマスクに独自トークンが送信された

Ropstenでやりたいが、Ethの取得が中々うまくいかない。。
が、基本的な仕組みは理解した