Hope is a Dream. Dream is a Hope.

非公開ふぃふぃ工房ブログ

UbuntuでEthereum その1(2017年6月版)

UbuntuでEthereum その1(2017年6月版)

参考 http://qiita.com/hshimo/items/8b69975d40466022f278

ポイント –devオプションを使い開発用gethを立ち上げる.(DAG等の大きなファイル作成の必要がなくなる)

gethを使うまでには

  1. Ubuntuにgethをインストールする
  2. gestion.jsonファイルを作成する
  3. gethを初期化する
  4. personを作成する
  5. personをunlockする
  6. マイニングする
  7. 送金する
  8. トランザクションの確認

記事執筆時点でのバージョン

geth 1.6

1. ubuntuにgethをインストールする

ubuntuの場合はapt-getでインストール可能

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を作成する

mining book.ethereum-jp.net

> 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. 送金する

etherを送金する

> 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])

- net
> net.listening
> net.peerCount

NAudioで信号処理 (その1)

チュートリアル その1

NAudioを使ってWaveファイルの再生

C# Audio Tutorial 1 - Wave File with NAudio

f:id:hope_is_dream:20170505192539p:plain

肝は、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)

f:id:hope_is_dream:20170506170929p:plain

NAudio.Gui.WaveViewerをカスタムしてグラフ描画!

www.youtube.com

いよいよグラフ描画です。信号処理はグラフを描画することから始まります。チュートリアルでは独自グラフの実装ではなく、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
    }
}