2017年8月31日 星期四

什麼是 ERC20 token

先說明 ERC-20 Token

erc20 是公認的 token interface, 定義了一個 token 應該要有哪些 functionalities,原始提案在這:https://github.com/ethereum/EIPs/issues/20

基本上有以下功能


  • totalSupply - 得知目前 token supply 的狀態
  • balanceOf - 得知特定 Account 的 Balance
  • transfer - 可以轉帳
  • approve - 授權的 Account 幫你轉帳一定額度
  • transferFrom - 從授權給你的 Account 轉帳
  • allowance - 查看授權給你的 Account 還有多少餘額可以讓你用
  • event Transfer - 轉帳發生後的 Event
  • event Approval - Triggered when approve called


https://theethereum.wiki/w/index.php/ERC20_Token_Standard



基本上現在市面上看到的各種幣有很多都是基於 Ethereum 上的 ERC20 Tokens

Deploy contract from truffle to testnet


Truffle 設定新的 network
Geth 開啟 test net
Deploy!

In geth console
```
personal.unlockAccount(eth.accounts[0])
```

```sh
truffle migrate --network ropsten
```



```
module.exports = {
  networks: {
    development: {
      host: "localhost",
      port: 8545,
      network_id: "*" // Match any network id
    },
     ropsten:  {
     network_id: 3,
     host: "localhost",
     port:  8545,
     gas:   2900000
}
  },
   rpc: {
 host: 'localhost',
 post:8080
   }
};
```


https://medium.com/@guccimanepunk/how-to-deploy-a-truffle-contract-to-ropsten-e2fb817870c1

rails 5 better redirect_to :back -> redirect_back(fallback_location: root_path)

redirect_back(fallback_location: root_path)


http://blog.bigbinary.com/2016/02/29/rails-5-improves-redirect_to_back-with-redirect-back.html

learn truffle and solidity - pet shop - note

* Public variables have automatic getter methods
* array getters return only a single value from a given key
* this, a contract-wide variable that gets the current contract's address
* Since the array contains address types, Ethereum initializes the array with 16 empty addresses

* Types
int: –2147483648 to 2147483647
uint: 0 to 4294967295
http://solidity.readthedocs.io/en/develop/types.html


```
mapping (address => uint) public balances;
```
=>
```
function balances(address _account) returns (uint) {
    return balances[_account];
}
```

* 跟 contract 一樣名稱的 function 就是 constructor




http://truffleframework.com/tutorials/pet-shop

2017年8月25日 星期五

Rails 5 support CURRENT_TIMESTAMP

rails5 現在 support CURRENT_TIMESTAMP 成為 default value 的寫法,但 annotate_model 的 gem 好像不會自動偵測到

```ruby
class CreatePosts < ActiveRecord::Migration[5.0]
  def change
    create_table :posts do |t|
      t.datetime :modified_at, default: -> { 'CURRENT_TIMESTAMP' }
      t.timestamps
    end
  end 
end
```

https://stackoverflow.com/questions/1580805/how-to-set-the-default-value-for-a-datetime-column-in-migration-script


https://github.com/rails/rails/pull/20005/files

DATETIME 和 TIMESTAMP 的差別

這邊說的是 database type

幾個結論

1. datetime 存了 date 和 time,可能用到 8 bit
2. datetime 可以支援的 range 比較廣,從 1000~9999 years 都可以
3. timestamp 則是存從 epoch time (1970-01-01) 到現在經過的秒數,只用到 4 bits
4. timestamp 因為存秒數,所以最早只能支援到 epoch time
5. timestamp 只用到 4 bits所以最多到 2038 年
6. rails migration 即使設 timestamp 也是使用 datetime 而不是用 timestamp


From wiki

Because DATETIME stores every digit in the year, month day, hour, minute and second, it uses up a total of 8 bytes. As TIMESTAMP only stores the number of seconds since 1970-01-01, it uses 4 bytes. You can read more about the differences between time formats in MySQL here.



https://stackoverflow.com/questions/3928275/in-ruby-on-rails-whats-the-difference-between-datetime-timestamp-time-and-da

怎麼在 rake task 裡面跑 task

最簡單:
task build: [
"migration:t15349:create_init_version_for_all_accounts",
"migration:t15349:migrate_account_version",
"migration:t15349:migrate_bcc_account_version"
]

或是

Rake::Task["build"].invoke

https://stackoverflow.com/questions/577944/how-to-run-rake-tasks-from-within-rake-tasks

Rails query tips


Exist

滿酷的用法之前沒想過

```ruby
# Post
scope :famous, ->{ where("view_count > ?", 1_000) }
# User
scope :without_famous_post, ->{
  where(_not_exists(Post.where("posts.user_id = users.id").famous))
}
def self._not_exists(scope)
  "NOT #{_exists(scope)}"
end
def self._exists(scope)
  "EXISTS(#{scope.to_sql})"
end
```

Subqueries

原來 rails 會自己 construct 這類的 sql

https://medium.com/@apneadiving/active-records-queries-tricks-2546181a98dd

2017年8月23日 星期三

rails 效能 - group

```
app/controllers/posts_controller.rb
def report
-  @posts = Post.all.include(:user).sort_by{ |post| post.subscriptions.size }.reverse[0,10]
+  @posts = Post.includes(:user).joins(:subscriptions).group("posts.id").select("posts.*, COUNT(subscriptions.id) as subscriptions_count").order("subscriptions_count DESC").limit(10)
end
```

```
app/views/posts/report.html.erb
-  <td><%= post.subscriptions.size %></td>
+  <td><%= post.subscriptions_count %></td>
```

2017年8月22日 星期二

Metaprograming 做 after method callback

Magic


```ruby
class Example
  def self.after(*names)
    names.each do |name|
      m = instance_method(name.to_s)
      # override old method
      define_method(name.to_s) do |*args, &block|
        m.bind(self).(*args, &block) # 這裡執行了 test method
        yield(self, name.to_sym, *args) # 這裡才是真正 callback 發生的地方
        self
      end
    end
  end

  def test(arg1, options)
    # do someting...
    # self => instance of Example
  end

  after(:test) do |example_instance, test_hash, arg1, options|
    #example_instance => instance of Example, self, from test method
    #test_hash => :test
  end
end
```

https://ruby-doc.org/core-2.2.0/UnboundMethod.html#method-i-bind

rails 可以自己定義 model callback

滿實用的,但應該少用,正常的 lifecycle 能夠滿足就不應該增加新的東西

想到最有可能會用的的地方就是搭配 sub/pub design pattern 的時候,例如 publish 後要 broadcast `published` event

http://vinsol.com/blog/2014/07/07/custom-model-callbacks-in-rubyonrails/

2017年8月17日 星期四

postgresql explain


可以看 sql 的複雜度和 cost,很方便的 sql command

https://www.postgresql.org/docs/9.4/static/using-explain.html

2017年8月15日 星期二

devise and warden - 登入失敗寄信

使用 lockable 或是不使用 lockable 都行

`DeviseController#require_no_authentication` 時會 call `warden.authenticate?`,這時會引發 `Lockable#valid_for_authentication?` 裡面的 `self.failed_attempts += 1`

也就是說當 code 運行到 `Devise::Users::SessionsController#create` 時就已經因為 before_action 而將 `failed_attempts` +1, 這時理論上只需要再 call `warden.authenticated?` 就可以知道是否驗證成功了

請把寄信邏輯寫在這(範例):

```ruby
  def create
    send_email if !warden.authenticated?
    super do |user|
      SendAdminLoginToSlack.perform_async(user.id) if user.supervisor?
      Sendcloud::SuccessfulLoginSender.perform_async(user.id) if login_with_different_ip?(user)
    end
    flash.delete :notice
  end
```

gem open gem_name -e editor

好方便的功能,不用再自己 clone 了

https://github.com/adamsanderson/open_gem

2017年8月13日 星期日

CSS Grid

推薦連結:

https://www.youtube.com/watch?v=txZq7Laz7_4&feature=share

TL;DR:

CSS grid 先把畫面切隔成不同的區塊後再把 content 丟到區塊裡,符合設計直覺
只套用第一層子元素
做 RWD 很方便,且省略了很多不必要的 nested elements

挺酷的

2017年8月1日 星期二

蒙地卡羅演算法

很簡單易懂的介紹,很棒

原理就是產生極多數的樣本,根據樣本的分佈狀態來預估真實狀態


其中交通堵塞的例子真的是很經典,很久以前就聽過但不知道是用蒙地卡羅演算法證明的

http://mp.weixin.qq.com/s/Ca6-zfA3LzijrMFhJcfnMA