---
# System prepended metadata

title: W3A analytics 安装步骤

---

# W3A analytics 安装步骤

## 一、安装TEE并运行

准备rust运行环境、安装sgx驱动 略）
1. 下载phala-blockchain源码
    ```
    git clone https://github.com/Phala-Network/phala-blockchain.git
    ```
2. `cd phala-blockchain; git submodule update --init`
3 编译TEE
    ```
    cd pruntime;SGX_MODE=SW make
    ```
4. 运行
    ```
    cd bin;./app
    ```

（TEE默认运行在8000端口）

## 二、安装W3A gateway

（安装ruby、rails 略）

1. 下载W3A gateway源码
    ```
    https://github.com/Phala-Network/w3a-gateway.git
    ```
2. `cd w3a-gateway`
3. 安装bundle
    ```
    bundle install
    ```
4. 复制数据库配置文件
    ```
    cp config/database.yml.sqlite3 config/database.yml
    ```
5. 创建数据库
    ```
    rails db:migrate
    ```
6. 初始化数据
    ```
    rails db:seed
    ```
7. 在7000端口运行gateway
    ```
    rails s -b 0.0.0.0 -p 7000
    ```

## 三、安装W3A后端

（安装node v12.16.2 略）

1. 下载w3a-backend源码
    ```
    git clone https://github.com/Phala-Network/w3a-backend.git
    ```
2. `cd w3a-backend`
3. 安装nodejs依赖
    ```
    npm install
    ```
4. 检查main.js里的数据库文件路径是否正确
```js
const db = new sqlite("../w3analytics/db/development.sqlite3");
```
5. 在/etc/systemd/system目录下创建w3a_backend.service文件，内容如下：
    ```service
    [Unit]
    Description=w3a backend daemon 

    [Service]
    ExecStart=/usr/local/bin/node /home/goldenfiredo/w3a-bakcend/main.js
    Restart=always
    User=root
    Group=root
    Environment=PATH=/usr/bin:/usr/local/bin
    Environment=NODE_ENV=production
    WorkingDirectory=/home/goldenfiredo/w3a-bakcend

    [Install]
    WantedBy=multi-user.target
    ```
6. 以service运行
    ```
    sudo systemctl start w3a_backend
    ```
    - 如果不以service方式运行，5、6步省略，直接运行node main.js    

7. 运行测试网页

    - 安装依赖：cd web_server;npm install
    - 根据实际配置修改页面脚本里的参数，index.html、page1.html、page2.html
        ```html
        <script>
          (function(t){
            window.w3a=window.w3a||function(){
              (window.w3a.q=window.w3a.q||[]).push(arguments)
            };
            o=document.createElement('script');
            m=document.getElementsByTagName('script')[0];
            o.async=1; o.src=t; o.id='w3a-script';
            m.parentNode.insertBefore(o,m)
          })("http://localhost:7000/tracker.js");
          w3a('set', 'siteId', '1');
          w3a('set', 'trackerUrl', "http://localhost:7000");
          w3a('generateClientId');
          setTimeout(function () {
            w3a('trackPageview');
          }, 500);
          </script>
          ```
    - 测试网页运行在9000端口，可根据需要修改，server.js：
    var httpServer = http.createServer(app);
    httpServer.listen(9000)
    - 在/etc/systemd/system目录下创建w3a_webserver.service文件，内容如下：
        ```service
        [Unit]
        Description=w3a demo web server daemon 

        [Service]
        ExecStart=/usr/local/bin/node /home/goldenfiredo/w3a-bakcend/web_server/server.js
        Restart=always
        User=root
        Group=root
        Environment=PATH=/usr/bin:/usr/local/bin
        Environment=NODE_ENV=production
        WorkingDirectory=/home/goldenfiredo/w3a-bakcend/web_server/

        [Install]
        WantedBy=multi-user.target
        ```
    - 以servcie运行
        ```
        sudo systemctl start w3a_webserver
        ```
        - 如果不以service方式运行，以上2步省略，直接运行node server.js
    - 打开浏览器访问此web: http://localhost:9000/index.html

8. 开始demo 

## 关于测试

W3A合约的测试代码位于pruntime/app/src目录下tests.rs模块，测试前需要将编译好的enclave.signed.so和spid.txt文件拷贝到pruntime/app目录下，测试时当前目录应为pruntime/app。

测试某个case，运行SGX_MODE=SW cargo test case名称，例如
```
SGX_MODE=SW cargo test test_w3a_setpageview
```

测试所有case，运行
```
SGX_MODE=SW cargo test -- --test-threads=1
```


## 关于添加用户控制开关

用户可以通过push command把自己的偏好设置送进TEE。目前只设置当统计数据时是否包含自己的数据。

1. 页面以某种方式获得用户的phala帐号公钥，然后页面脚本加入一行：

    ```javascript
    w3a('set', 'uid', '16进制公钥');
    ```
    ```html
    <script>
      (function(t){
        window.w3a=window.w3a||function(){
          (window.w3a.q=window.w3a.q||[]).push(arguments)
        };
        o=document.createElement('script');
        m=document.getElementsByTagName('script')[0];
        o.async=1; o.src=t; o.id='w3a-script';
        m.parentNode.insertBefore(o,m)
      })("http://localhost:7000/tracker.js");
      w3a('set', 'siteId', '1');
      w3a('set', 'uid', 'de54ad82393c4afb9b47d283867c7d2b7205d309ef19f7a9b0bd969d99ebb20d');
      w3a('set', 'trackerUrl', "http://localhost:7000");
      w3a('generateClientId');
      setTimeout(function () {
        w3a('trackPageview');
      }, 500);
    </script>
    ```
  
2. 修改tracker.js脚本使其能接收uid参数[https://ipfs.io/ipfs/QmX24qVFoi9dg7PGiKka9vFrHcPkgJTJnE4nWEGx8Yzup9](https://ipfs.io/ipfs/QmX24qVFoi9dg7PGiKka9vFrHcPkgJTJnE4nWEGx8Yzup9)
3. 数据库表page_views添加uid varchar字段
4. 修改collectors_controller.rb，将tracker.js接收的uid写入数据库
5. 用户通过前端UI的extrincs提交comand（Plain mode）

![](https://i.imgur.com/RHDkpJN.png)

其中，如下 payload 表示打开开关，用户的访问数据不统计：

> 7b22506c61696e223a227b5c22536574436f6e66696775726174696f6e5c223a7b5c22736b69705f737461745c223a747275657d7d227d
> 对应 {"Plain":"{\\\"SetConfiguration\\\":{\\\"skip_stat\\\":true}}"}

如下 payload 表示关掉开关：

> 7b22506c61696e223a227b5c22536574436f6e66696775726174696f6e5c223a7b5c22736b69705f737461745c223a66616c73657d7d227d
> 对应 {"Plain":"{\\\"SetConfiguration\\\":{\\\"skip_stat\\\":false}}"}

如果用户页面不设置uid或uid为空，统计时包含该用户数据。

在demo网页里，首页index.html里uid为空，模拟用户没有绑定帐号公钥的情况，因此这个页面中用户数据不受控制。

`page1.html`、`page2.html` 里模拟了用户绑定帐号公钥的情况，测试用户主动控制开关时需要在polkadot.js上导入对应的助记词：

> page1.html
> 公钥: `de54ad82393c4afb9b47d283867c7d2b7205d309ef19f7a9b0bd969d99ebb20d`
> 助记词: aisle release muscle sample slogan garment blood change pig cable vital better

> page2.html
> 公钥: 86b0c7b9e2eec91916a9f89e7a8354c1f720840c342de87d35f77b9bc2d4bb0e
> 助记词: federal away away harvest frog sustain holiday innocent address note cup early。

6. 合约和w3a-backend修改见repo


## 关于 W3A dockerfile

W3A 合约支持在docker里运行、测试。步骤如下：

1. 安装docker应用并运行dockerd
2. 下载源码
    ```
    git clone https://github.com/Phala-Network/phala-blockchain.git
    ```
3. 更新子模块
    ```
    git submodule update --init
    ```
4. Build docker image
    ```
    docker build -f w3a.Dockerfile -t w3a .
    ```
5. Run docker
    ```
    docker run -it -p 7000:7000 -p 9000:9000 --env DOCKER_IP=10.86.1.3 w3a
    ```

其中的DOCKER_IP是本地docker的ip地址，一般为172.17.0.1；如果是通过代理访问远程docker，请使用代理地址，如10.86.1.3。

> 如果需要开启代理构建Docker，可以采用如下命令
> ```
> docker build --build-arg HTTP_PROXY=http://192.168.199.10:7890 --build-arg > HTTPS_PROXY=http://192.168.199.10:7890 --build-arg http_proxy=http://192.168.199.10:7890 --build-arg https_proxy=http://192.168.199.10:7890 -f w3a.Dockerfile -t w3a .
> ```
> 其中 192.168.199.10 是本机的 IP 地址

![](https://i.imgur.com/nlbAQWL.png)
（启动成功后界面）

6. 查询统计结果
    - 打开浏览器输入网址http://10.86.1.3:9000/，用户的每次点击事件都会加密后记入后端数据库
![](https://i.imgur.com/5vDaTip.png)

    - 使用docker container ls命令获得w3a容器ID，记下前4个字母。如abcd
    - 数据库中原始数据和统计数据的关键字段都是加密的，通过docker的exec命令可以输出显示
    - 查询原始数据： docker exec abcd bash /root/w3a_query_page_views.sh
    - 查询统计结果： docker exec abcd bash /root/w3a_query_statistics.sh
    - 为了便于检查结果是否正确，数据可解密后输出：
        ```
        docker exec abcd bash /root/w3a_query_page_views.sh decrypt
        ```
        ![](https://i.imgur.com/WYfunps.png)

        ```
        docker exec abcd bash /root/w3a_query_statistics.sh decrypt
        ```
        ![](https://i.imgur.com/zAk5E6j.png)
7. 清除测试数据：
    ```
    docker exec abcd bash /root/w3a_db_clear.sh
    ```














