UbuntuでEthereum その1(2017年6月版)
UbuntuでEthereum その1(2017年6月版)
参考 http://qiita.com/hshimo/items/8b69975d40466022f278
ポイント –devオプションを使い開発用gethを立ち上げる.(DAG等の大きなファイル作成の必要がなくなる)
gethを使うまでには
- Ubuntuにgethをインストールする
- gestion.jsonファイルを作成する
- gethを初期化する
- personを作成する
- personをunlockする
- マイニングする
- 送金する
- トランザクションの確認
記事執筆時点でのバージョン
geth 1.6
1. ubuntuにgethをインストールする
sudo apt-get install software-properties-common sudo add-apt-repository -y ppa:ethereum/ethereum sudo apt-get update sudo apt-get install ethereum
2.1. 環境を作る
まずはイーサリアムの環境を作るディレクトリを作成する. ここではhome/fifi/ethereumとする.
mkdir /home/fifi/ethereum
2.2. gestion.jsonファイルを作成する
genesis.json genesis.jsonファイルを作業スペース(/home/fifi/ethereum/genesis.json)下に格納する.
{ "config": { "chainId": 15, "homesteadBlock": 0, "eip155Block": 0, "eip158Block": 0 }, "difficulty": "200000000", "gasLimit": "2100000", "alloc": { "7df9a875a174b3bc565e6424a0050ebc1b2d1d82": { "balance": "300000" }, "f41c74c9ae680c1aa78f42e5647a62f353b7bdde": { "balance": "400000" } } }
2.3 プライベートネットワークを初期化
geth --datadir /home/fifi/ethereum init genesis.json // 下でも初期化できた cd /home/fifi/ethereum geth --datadir ./ init ./genesis.json // 開発用でgethを立ち上げたい場合は、--devオプションをつける. geth --dev --datadir ./ init ./genesis.json
初期化した後にこのデータディレクトリにアクセスするには以下のコマンドを実行する
geth --datadir ./ console
起動には複数のオプションがある
--datadir /home/fifi/ethereum/ : data-dir-path --networkid 15 : 仮想ネットワークのID(適当) (例)1, 12, 100 --bootnodes <bootnode-enode-url-from-above> : --mine: mining enable --minerthreads=1 --etherbase=0x0000000000 : etherbaseとなるアカウントの指定
3.1. personを作成する
> personal.newAccount("user1") INFO [06-26|14:07:03] New wallet appeared url=keystore:///home/fifi/.ethereum… status=Locked "0x3260c0b494dd9b8715d02bbbfdc6527135ad97b6"
指定する文字列(例では"user1")がパスワード
となるので覚えておく.(Unlock時に使用する)
3.2 personのUnlock
> personal.unlockAccount(eth.accounts[0]) Unlock account 0x3260c0b494dd9b8715d02bbbfdc6527135ad97b6 Passphrase: (パスワードを入れる) true
3.3 etherbaseを設定する
マイニングした報酬をあるアカウントに紐つけます
> miner.setEtherbae(eth.acthcounts[0]) > eth.coinbase '0x59c444d6c4f4187d1dd1875ad74a558a2a3e20b6'
4. 送金する
> eth.accounts // 登録されている2つのアカウントを表示。 ['0x24afe6c0c64821349bc1bfa73110512b33fa18e1', '0x59c444d6c4f4187d1dd1875ad74a558a2a3e20b6' ] > eth.getBalance(eth.accounts[0]) // etherbaseである1番目のアカウントにetherの持ち高がある(採掘の報酬)。 '72500000000000000000' > eth.getBalance(eth.accounts[1]) // 2番目のアカウントにはetherの持ち高はない。 '0'
トランザクションを作成する
> eth.sendTransaction({from: eth.accounts[0], to: eth.accounts[1], value: web3.toWei(5, "ether")}) //送金の実行。アカウントのパスワードの入力を求められるので従う。実行結果としてトランザクションIDが返される。 Please unlock account 24afe6c0c64821349bc1bfa73110512b33fa18e1. Passphrase: Account is now unlocked for this session. '0xc86c2a5bdf651f54095eca87e487d4f68f12030dd559f0377e9e7bf1566b9b28' →トランザクションの番号
トランザクションの情報を調べる
先に送信したトランザクションの番号を控えておき,情報を調べる
> eth.getTransaction('0x5fd0bdcccb379a8b4034668464ad9a499a8a6b7801ed66ac23e4df3d67ec64a5') { blockHash: '0xeef0f74bc51ecb9f3d64099fa4f3c1651af36a632380d41dd987e8e7064a5276', blockNumber: 11076, from: '0x868d840e872df5134a3be6f7b68e52cb680fe3ac', gas: 90000, gasPrice: '55928534329', hash: '0x5fd0bdcccb379a8b4034668464ad9a499a8a6b7801ed66ac23e4df3d67ec64a5', input: '0x', nonce: 0, to: '0x2efbdc840746c862b63077643e5b7dd8bebb8448', transactionIndex: 0, value: '3000000000000000000' }
トランザクションを送っただけでは,送金はされない.だれかがマイニングする必要がある.
自分でマイニングする.
miner.start()
適当なところでストップ
miner.stop()
> eth.getTransaction("0x0f61531af0dd600fd37cf0eb85cb131fc87d37d06c4e00b95cf1c847e612a640") { blockHash: "0x936cd2d85afc1eefa6c0f4f81555c75a0c9e62b4f3780f2dafe769d33cd93948", blockNumber: 208, from: "0xdce41c68345bf699aa82ca2cce29fdf58e4b3b45", gas: 90000, gasPrice: 0, hash: "0x0f61531af0dd600fd37cf0eb85cb131fc87d37d06c4e00b95cf1c847e612a640", input: "0x", nonce: 0, r: "0x285a39079b67c3e3a509bdba4746342accb96093d3810419c9a2681c39c7ead5", s: "0x619519553f55c555acfcbfdba69a251446bc3baf1f00c51783de3c3fd6c61b1d", to: "0xffa054f546f2edf37d0515f531421ffecbb55ef8", transactionIndex: 0, v: "0xa96", value: 3000000000000000000 }
内容の詳細はチュートリアルを参照 https://book.ethereum-jp.net/first_use/sending_ether.html
> eth.getBalance(eth.accounts[1]) 3000000000000000000 etherが増えていることを確認
リファレンス
コマンド一覧
- 起動 geth console geth --bootnodes "enode://pubkey1@ip1:port1 enode://pubkey2@ip2:port2 enode://pubkey3@ip3:port3" geth --dev console - personal personal.newAccount(); personal.unlockAccount(eth.account[0]) - eth eth.getBalance(eth.accounts[0]) eth.sendTransaction({from: eth.accounts[1], to: eth.accounts[0], value: web3.toWei(3, "ether")}) - admin admin.nodeInfo admin.addPeer(enodeUrlOfFirstInstance) -miner miner.start() miner.stop() miner.setEtherbae(eth.accounts[0]) '''
NAudioで信号処理 (その1)
チュートリアル その1
NAudioを使ってWaveファイルの再生
C# Audio Tutorial 1 - Wave File with NAudio
肝は、WAVファイルをロードして、DIrectSoundで再生する。
wave = new NAudio.Wave.WaveFileReader(open.FileName); output = new NAudio.Wave.DirectSoundOut(); output.Init(new NAudio.Wave.WaveChannel32(wave)); output.Play();
メインのソースコードは以下のようになる。WAVの再生には、WAVファイルの選択->WAVのReaderの設定->出力先を指定->再生開始。のほかにも再生中断/再開や、再生が停止されたときのDispose処理が関わってくる。このチュートリアル(その1)では基本的なWAVファイル再生をベースとして、周辺のプレ処理、クロージング処理を実装しているので注目して欲しい。
using System; using System.Windows.Forms; namespace Tutorial1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { button_PauseWav.Enabled = false; } private NAudio.Wave.WaveFileReader wave = null; private NAudio.Wave.DirectSoundOut output = null; private void button_OpenWav_Click(object sender, EventArgs e) { OpenFileDialog open = new OpenFileDialog(); open.Filter = "Wave File (*.wav,*.WAV) |*.wav;*.WAV;|All files (*.*)|*.*"; if (open.ShowDialog() != DialogResult.OK) return; DisposeWave(); wave = new NAudio.Wave.WaveFileReader(open.FileName); output = new NAudio.Wave.DirectSoundOut(); output.Init(new NAudio.Wave.WaveChannel32(wave)); output.Play(); button_PauseWav.Enabled = true; } private void button_PauseWav_Click(object sender, EventArgs e) { if (output != null) { if (output.PlaybackState == NAudio.Wave.PlaybackState.Playing) output.Pause(); else if (output.PlaybackState == NAudio.Wave.PlaybackState.Paused) output.Play(); } } // Wave関連のインスタンスをDispose private void DisposeWave() { if (output != null) { if (output.PlaybackState == NAudio.Wave.PlaybackState.Playing) output.Stop(); output.Dispose(); output = null; } if (wave != null) { wave.Dispose(); wave = null; } } // フォームが閉じられたとき、Wave関連のインスタンスをDispose private void Form1_FormClosing(object sender, FormClosingEventArgs e) { this.DisposeWave(); } } }
NAudioで信号処理 (その11)
NAudioで信号処理 (目次) - Hope is a Dream. Dream is a Hope.
NAudioで信号処理 2 (その11)
NAudio.Gui.WaveViewerをカスタムしてグラフ描画!
いよいよグラフ描画です。信号処理はグラフを描画することから始まります。チュートリアルでは独自グラフの実装ではなく、chartクラスと、NAudioのWaveViewerクラスを使っての実装となります。
CustomWaveViewer
NAudio.Gui.WaveViewerをコピペして、ズームやらフィットやらをカスタム
using System; using System.Collections; using System.ComponentModel; using System.Drawing; using System.Data; using System.Windows.Forms; using NAudio.Wave; namespace Tutorial { /// <summary> /// Control for viewing waveforms /// </summary> public class CustomWaveViewer : System.Windows.Forms.UserControl { #region プロパティ public Color PenColor { get; set; } public float PenWidth { get; set; } #endregion public void FitToScreen() { if (waveStream == null) return; int samples = (int)(waveStream.Length / bytesPerSample); this.startPosition = 0; this.SamplesPerPixel = samples / this.Width; } public void Zoom(int leftSample, int rightSample) { this.startPosition = leftSample * bytesPerSample; // [byte] this.SamplesPerPixel = (rightSample - leftSample) / this.Width; // [sample/pixel] } #region Mouse private Point mousePos, startPos; private bool mouseDrag = false; protected override void OnMouseDown(MouseEventArgs e) { if (e.Button == System.Windows.Forms.MouseButtons.Left) { startPos = e.Location; mousePos = new Point(-1, 1); mouseDrag = true; DrawVerticalLine(e.X); } base.OnMouseDown(e); } protected override void OnMouseMove(MouseEventArgs e) { if (mouseDrag) { DrawVerticalLine(e.X); // マウス位置にライン描画 if (mousePos.X != -1) DrawVerticalLine(mousePos.X); //前のラインを消す mousePos = e.Location; } base.OnMouseMove(e); } protected override void OnMouseUp(MouseEventArgs e) { if (mouseDrag && e.Button == System.Windows.Forms.MouseButtons.Left) { mouseDrag = false; DrawVerticalLine(startPos.X); if (mousePos.X == -1) return; DrawVerticalLine(mousePos.X); int leftSample = (int)(StartPosition / bytesPerSample + SamplesPerPixel * Math.Min(startPos.X, mousePos.X)); int rightSample = (int)(StartPosition / bytesPerSample + SamplesPerPixel * Math.Max(startPos.X, mousePos.X)); Zoom(leftSample, rightSample); }else if(e.Button == MouseButtons.Middle){ this.FitToScreen(); } base.OnMouseUp(e); } #endregion private void DrawVerticalLine(int x) { ControlPaint.DrawReversibleLine( PointToScreen(new Point(x, 0)), PointToScreen(new Point(x, Height)), Color.Black); } protected override void OnResize(EventArgs e) { this.FitToScreen(); base.OnResize(e); } /// <summary> /// Required designer variable. /// </summary> private System.ComponentModel.Container components = null; private WaveStream waveStream; private int samplesPerPixel = 128; private long startPosition; private int bytesPerSample; /// <summary> /// Creates a new WaveViewer control /// </summary> public CustomWaveViewer() { // This call is required by the Windows.Forms Form Designer. InitializeComponent(); this.DoubleBuffered = true; this.PenColor = Color.DodgerBlue; this.PenWidth = 1; } /// <summary> /// sets the associated wavestream /// </summary> public WaveStream WaveStream { get { return waveStream; } set { waveStream = value; if (waveStream != null) { bytesPerSample = (waveStream.WaveFormat.BitsPerSample / 8) * waveStream.WaveFormat.Channels; } this.Invalidate(); } } /// <summary> /// The zoom level, in samples per pixel /// </summary> public int SamplesPerPixel { get { return samplesPerPixel; } set { samplesPerPixel = Math.Max(1, value); this.Invalidate(); } } /// <summary> /// Start position (currently in bytes) /// </summary> public long StartPosition { get { return startPosition; } set { startPosition = value; } } /// <summary> /// Clean up any resources being used. /// </summary> protected override void Dispose(bool disposing) { if (disposing) { if (components != null) { components.Dispose(); } } base.Dispose(disposing); } /// <summary> /// <see cref="Control.OnPaint"/> /// </summary> protected override void OnPaint(PaintEventArgs e) { if (waveStream != null) { waveStream.Position = 0; int bytesRead; byte[] waveData = new byte[samplesPerPixel * bytesPerSample]; waveStream.Position = startPosition + (e.ClipRectangle.Left * bytesPerSample * samplesPerPixel); using (Pen linePen = new Pen(PenColor, PenWidth)) { for (float x = e.ClipRectangle.X; x < e.ClipRectangle.Right; x += 1) { short low = 0; short high = 0; bytesRead = waveStream.Read(waveData, 0, samplesPerPixel * bytesPerSample); if (bytesRead == 0) break; for (int n = 0; n < bytesRead; n += 2) { short sample = BitConverter.ToInt16(waveData, n); if (sample < low) low = sample; if (sample > high) high = sample; } float lowPercent = ((((float)low) - short.MinValue) / ushort.MaxValue); float highPercent = ((((float)high) - short.MinValue) / ushort.MaxValue); e.Graphics.DrawLine(linePen, x, this.Height * lowPercent, x, this.Height * highPercent); } } } base.OnPaint(e); } #region Component Designer generated code /// <summary> /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// </summary> private void InitializeComponent() { components = new System.ComponentModel.Container(); } #endregion } }