咸鱼

咸鱼是以盐腌渍后,晒干的鱼

0%

智能合约,我理解它就是程序机器码,可以在区块链上执行的代码,好比 C语言的*.o 文件,Java的 *.class 文件。

  1. 启动 私有链,我们的程序(合约)就跑在这条私有链上。

    1
    $ geth --datadir data0 --networkid 1108 --nodiscover console
  2. 查看挖矿账户

    1
    2
    > web3.eth.coinbase 
    "0x5400ca57071e4d804e1d5f7c14f63a70fa90d541"
  3. 编写solidity代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    pragma solidity ^0.4.0;

    contract HelloWorld {

    function test(uint a) constant returns(uint d){

    return a * 8;
    }
    }
  4. 编译为字节码和abi

    在线编译compile - Start To compile -> Details

    bytecode 只要 object 的值,abi 全部拷贝。

    注:Details -> web3Deploy有部署的示例,但我们自己手动来一遍。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    # bytecode
    6060604052341561000f57600080fd5b60b98061001d6000396000f300606060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806329e99f07146044575b600080fd5b3415604e57600080fd5b606a600480360381019080803590602001909291905050506080565b6040518082815260200191505060405180910390f35b60006008820290509190505600a165627a7a7230582079ee88ca1fe7e781407b09bc2c5497dcabc538d6930265a54386d2b71b0cd7510029

    # abi
    [
    {
    "constant": true,
    "inputs": [
    {
    "name": "a",
    "type": "uint256"
    }
    ],
    "name": "test",
    "outputs": [
    {
    "name": "d",
    "type": "uint256"
    }
    ],
    "payable": false,
    "stateMutability": "view",
    "type": "function"
    }
    ]
    # abi转义
    [{\"constant\":true,\"inputs\":[{\"name\":\"a\",\"type\":\"uint256\"}],\"name\":\"test\",\"outputs\":[{\"name\":\"d\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}]
  5. 创建合约对象

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    # 赋值为本地变量。
    # 因为是十六进制,加上 0x 赋值给 bytecode
    >
    > bytecode = '0x6060604052341561000f57600080fd5b60b98061001d6000396000f300606060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806329e99f07146044575b600080fd5b3415604e57600080fd5b606a600480360381019080803590602001909291905050506080565b6040518082815260200191505060405180910390f35b60006008820290509190505600a165627a7a7230582079ee88ca1fe7e781407b09bc2c5497dcabc538d6930265a54386d2b71b0cd7510029'
    >
    # abi要解析为对象。
    > var abi = JSON.parse('[{\"constant\":true,\"inputs\":[{\"name\":\"a\",\"type\":\"uint256\"}],\"name\":\"test\",\"outputs\":[{\"name\":\"d\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}]')
    >
    > var helloWorldContract = web3.eth.contract(abi)
    undefined
  6. 预估部署合约的手续费

    1
    2
    3
    4
    5
    6
    > eth.estimateGas({data: bytecode})
    102074
    # 查看余额,如果账户的余额不够,先挖矿。
    > account1 = web3.eth.coinbase
    > web3.eth.getBalance(account1)
    600000000000000000000
  7. 部署

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    # 解锁
    > personal.unlockAccount(account1, '123456')
    true
    # 部署,gas 是手续费
    > var helloWorldContractInstance = helloWorldContract.new({data: bytecode ,gas: 2000000, from: account1})
    # 或者带上一个回调函数function,用于打印日志
    > var helloWorldContractInstance = helloWorldContract.new(
    {
    data: bytecode,
    gas: 2000000,
    from: account1
    }, function (e, contract){
    console.log(e, contract);
    if (typeof contract.address !== 'undefined') {
    console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);
    }
    })

    # log看到,合约已经创建
    INFO [03-30|20:50:12] Submitted contract creation fullhash=0x583c5c0e6f8c2225cd8411b1ba0a58304505aea929d6c9cd1c0773c952657416 contract=0x05E4898E94785523c6C5AcBa4324B529B5197Bcf
    null [object Object]
    undefined
  8. 合约等待挖矿,开始挖矿

    合约需要有节点在挖矿才能部署成功,所以我们先启动挖矿。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    > miner.start()
    INFO [03-30|20:51:30] Updated mining threads threads=0
    INFO [03-30|20:51:30] Transaction pool price threshold updated price=18000000000
    null
    # 这里等待一会
    > INFO [03-30|20:51:30] Starting mining operation
    INFO [03-30|20:51:30] Commit new mining work number=195 txs=1 uncles=0 elapsed=998.832µs
    INFO [03-30|20:51:46] Successfully sealed new block number=195 hash=d60b89…65bffe
    INFO [03-30|20:51:46] 🔗 block reached canonical chain number=190 hash=4159ba…196761
    INFO [03-30|20:51:46] 🔨 mined potential block number=195 hash=d60b89…65bffe
    INFO [03-30|20:51:46] Commit new mining work number=196 txs=0 uncles=0 elapsed=7.087ms
    null [object Object]
    Contract mined! address: 0x05e4898e94785523c6c5acba4324b529b5197bcf transactionHash: 0x583c5c0e6f8c2225cd8411b1ba0a58304505aea929d6c9cd1c0773c952657416
    INFO [03-30|20:51:55] Successfully sealed new block number=196 hash=f6a947…15b0a4
    INFO [03-30|20:51:55] 🔗 block reached canonical chain number=191 hash=c95b93…bdd2a6
    INFO [03-30|20:51:55] 🔨 mined potential block number=196 hash=f6a947…15b0a4
    INFO [03-30|20:51:55] Commit new mining work number=197 txs=0 uncles=0 elapsed=2.289ms
    # 只要挖矿成功了,就可以停止了
    > miner.stop()
    true
  9. 检查部署结果和调用合约方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    > helloWorldContractInstance.address
    "0x05e4898e94785523c6c5acba4324b529b5197bcf"
    >
    > eth.getCode(helloWorldContractInstance.address)
    "0x606060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806329e99f07146044575b600080fd5b3415604e57600080fd5b606a600480360381019080803590602001909291905050506080565b6040518082815260200191505060405180910390f35b60006008820290509190505600a165627a7a7230582079ee88ca1fe7e781407b09bc2c5497dcabc538d6930265a54386d2b71b0cd7510029"
    >
    >
    > helloWorldContractInstance.test(4)
    32
  10. OK

为什么要搭建私有链?

在以太坊的公有链上部署智能合约、发起交易需要花费以太币,要同步公有链数据块(xGB)。而在私有链,上面这些都不用,我们进行智能合约开发测试就很方便了,开发完成了,再部署到公有链。

环境

vmware内的ubuntu14.04,字符终端,通过ssh连接。

安装Geth
1
2
3
4
sudo apt-get install software-properties-common
sudo add-apt-repository -y ppa:ethereum/ethereum
sudo apt-get update
sudo apt-get install ethereum
阅读全文 »

  1. 下载工程

    1
    $ git clone https://github.com/spring-io/initializr.git
  2. 构建打包

    1
    2
    3
    4
    5
    6
    $ cd initializr/
    $ mvn compile
    $ mvn package -Dmaven.test.skip=true

    # 或者直接一条命令安装到本地maven库
    $ mvn clean install -Pfull
  3. 运行

    1
    2
    3
    4
    # package打包,在initializr-service/target/下可以找到jar包
    # install的在 ~/.m2/repository/io/spring/initializr/initializr-service/x.x.x.BUILD-SNAPSHOT

    $ java -jar init.jar --server.port=8089
  4. OK

2018年3月20日 JDK 10 发布,非LTS 版本。

新特性: http://openjdk.java.net/projects/jdk/10/

  • 286: Local-Variable Type Inference
  • 296: Consolidate the JDK Forest into a Single Repository
  • 304: Garbage-Collector Interface
  • 307: Parallel Full GC for G1
  • 310: Application Class-Data Sharing
  • 312: Thread-Local Handshakes
  • 313: Remove the Native-Header Generation Tool (javah)
  • 314: Additional Unicode Language-Tag Extensions
  • 316: Heap Allocation on Alternative Memory Devices
  • 317: Experimental Java-Based JIT Compiler
  • 319: Root Certificates
  • 322: Time-Based Release Versioning

中文
* 286: 局部变量类型推断 (var x = “hello”)
* 296: Consolidate the JDK Forest into a Single Repository
* 304: Garbage-Collector Interface
* 307: G1并行全垃圾回收器 Parallel Full GC for G1
* 310: 应用类数据共享(CDS)
* 312: 线程-局部变量管控
* 313: 删除 Native-Header 自动生成工具 (javah)
* 314: 额外的 Unicode 语言标签扩展
* 316: 在备用存储装置上的堆分配
* 317: 试验性的基于 Java 的 JIT 编译器
* 319: 根证书Root Certificates
* 322: 基于时间的版本控制

Java 10 正式发布于 2018 年 3 月 21 日,Java 10 版本带来了很多新特性,其中最备受广大开发者关注的莫过于局部变量类型推断。除此之外,还有其他包括垃圾收集器改善、GC 改进、性能提升、线程管控等一批新特性。

阅读全文 »

使用场景举例
  1. 在家里的电脑用 putty 登录到公司内网的测试服务器
  2. 将内网的测试服务(如 HTTP/Git/Svn,只要是基于 TCP 的就行)提供到公网

场景二 还可以通过路由器端口映射转发来实现,但是不是每个人都能控制公司的路由器,没有固定 IP 也是一个麻烦事。另外还可以通过 ngrok 等工具来转发,ngrok 还是有点慢,没有公网服务器时是一个不错的选择。

部署条件
  1. 有一台公网服务器,如阿里云的ESC。
阅读全文 »

  • ES非常适用于搜索,速度快,使用简单。

  • 全文搜索——一种传统数据库很难实现的功能

  • 非常容易进行分布式 / 集群部署。

  • 想到再写。

上车

本文是拷贝 google.cn ,更新时间是文章的发表时间。

搭配使用 Android Studio 2.2 或更高版本与 Android Plugin for Gradle 版本 2.2.0 或更高版本时,您可以将 C 和 C++ 代码编译到 Gradle 与 APK 一起打包的原生库中,将这类代码添加到您的应用中。您的 Java 代码随后可以通过 Java 原生接口 (JNI) 调用您的原生库中的函数。如果您想要详细了解如何使用 JNI 框架,请阅读 Android 的 JNI 提示。

Android Studio 用于构建原生库的默认工具是 CMake。由于很多现有项目都使用构建工具包编译其原生代码,Android Studio 还支持 ndk-build。如果您想要将现有的 ndk-build 库导入到您的 Android Studio 项目中,请参阅介绍如何配置 Gradle 以关联到您的原生库的部分。不过,如果您在创建新的原生库,则应使用 CMake。

本页面介绍的信息可以帮助您使用所需构建工具设置 Android Studio、创建或配置项目以支持 Android 上的原生代码,以及构建和运行应用。

注:如果您的现有项目使用已弃用的 ndkCompile 工具,则应先打开 build.properties 文件,并移除以下代码行,然后再将 Gradle 关联到您的原生库

阅读全文 »

简单分析当前主流IOT的WiFi方案Smartlink

从原理上讲,只要芯片驱动支持开启混杂模式(WiFi Promiscuous),就可以支持一键配网功能,只是各个厂家叫法及实现编码方式不同而已。

SmartLink传送门

AirKiss传送门

注意:本文来自chaodongyang.com,点击阅读原文

java编程思想之并发(线程之间的协作)

当你使用多线程来同时运行多个任务时,可以通过使用锁来同步两个任务的行为,从而使的一个任务不会干涉另一个任务的资源。也就是说,如果两个任务交替的步入某项共享资源,你可以使用互斥来保证任何时刻只有一个任务可以访问这项资源。

线程之间的协作

上面的问题已经解决了,下一步是如何使得任务彼此之间可以协作,使得多个任务可以一起工作去解决某个问题。现在的问题不是彼此之间的干涉,而是彼此之间的协作。解决这类问题的关键是某些部分必须在其他部分被解决之前解决。
当任务协作时,关键问题是这些任务之间的握手。为了实现握手,我们使用了相同的基础特性:互斥。在这种情况下,互斥能够确保只有一个任务可以响应某个信号,这样就能根除任何可能的竞争条件。在互斥上,我们为任务添加了一种途径,可以将自身挂起,直至某些外部条件发生变化,表示是时候让这个任务开始为止。

阅读全文 »

注意:本文来自awesome,点击阅读原文

ICON图标

Logo 设计

阅读全文 »

wappalyzer,可以大概知道一个网站的服务器软件,使用的js库等信息。
原理的话,应该是网站响应的header信息。

以下是手动屏蔽固定的IP,还有一些方法可以自动将IP屏蔽待以后需要再研究。

1. 假设nginx的配置中有如下一个server

1
2
3
4
5
6
7
8
9
10
server {
listen 80;
server_name localhost;

location / {

root /var/www/localhost;
index index.html index.htm;
}
}

2. 如果现在我需要屏蔽两个IP,加入以下三行到server节点中:

1
2
3
4
# allow 一定要在 deny 前面
allow all;
deny 123.123.123.123;
deny 123.123.123.124;
阅读全文 »

很多嵌入式设备都有接入网络的功能,那么在Linux下的C,用什么HTTP库比较合适呢?嵌入式设备资源都比较紧张,大的库肯定不是一个好的选择。
由于不是专业的,只能找到以下库:

  • libcurl
    curl-7.56.1.zip 大小是5.27MB,里面包含了supporting HTTP, HTTPS, FTP, FTPS, GOPHER, TFTP, SCP, SFTP, SMB, TELNET, DICT, LDAP, LDAPS, FILE, IMAP, SMTP, POP3, RTSP and RTMP. 所以能精简出来HTTP是没有5.27MB那么大。

    而且一般linux系统都带有curl的库,c语言可以直接引入curl的头文件。

    libcurl基本知识post和get请求

    c/c++调用libcurl库发送http请求的两种基本用法

    示例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    #include<stdio.h>
    #include<curl/curl.h>
    #include<stdlib.h>

    int main(int argc, char *argv[])
    {
    CURL *curl; //定义CURL类型的指针
    CURLcode res; //定义CURLcode类型的变量,保存返回状态码

    if(argc!=2)
    {
    printf("Usage: file <url>;\n");
    exit(1);
    }

    curl = curl_easy_init(); //初始化一个CURL类型的指针

    if(curl!=NULL)
    {
    //设置curl选项.其中CURLOPT_URL是让用户指定url.argv[1]中存放的命令行传进来的网址
    curl_easy_setopt(curl,CURLOPT_URL, argv[1]);
    //调用curl_easy_perform执行我们的设置.并进行相关的操作.在这里只在屏幕上显示出来.
    res = curl_easy_perform(curl);
    //清除curl操作.
    curl_easy_cleanup(curl);
    }

    return 0;
    }
    1
    2
    3
    #编译和运行
    $ gcc test_curl.c -o test -lcurl
    $ ./test www.baidu.com
  • Tinyhttpd
    ​Tinyhttpd 是J. David Blackstone在1999年写的一个不到 500 行的超轻量型 Http Server

  • Boa
    ​Boa是一个非常小巧的web服务器,其可执行代码只有约60Kb

  • ghttp
    官网没有下载了,但根据其他下载站来看,只有144KB,要源码可以去github搜一下。封装示例

  • C++ client for making HTTP/REST requests

  • C++ Requests: Curl for People

  • tbox的http模块

  • 自己拼包

  • 无意中发现的一个库,里面封装了一些 HTTPClient 和其他IO的库

  • C++ client for making HTTP/REST requests

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
root@bogon:~# screenfetch
./+o+- root@bogon
yyyyy- -yyyyyy+ OS: Ubuntu 16.04 xenial
://+//////-yyyyyyo Kernel: x86_64 Linux 4.4.0-97-generic
.++ .:/++++++/-.+sss/` Uptime: 2d 9h 14m
.:++o: /++++++++/:--:/- Packages: 1004
o:+o+:++.`..```.-/oo+++++/ Shell: bash 4.3.48
.:+o:+o/. `+sssoo+/ CPU: 2x Intel Core i7-7500U CPU @ 2.904GHz
.++/+:+oo+o:` /sssooo. RAM: 638MiB / 974MiB
/+++//+:`oo+o /::--:.
\+/+o+++`o++o ++////.
.++.o+++oo+:` /dddhhh.
.+.o+oo:. `oddhhhh+
\+.++o+o``-````.:ohdhhhhh+
`:o+++ `ohhhhhhhhyo++os:
.o:`.syhhhhhhh/.oo++o`
/osyyyyyyo++ooo+++/
````` +oo+++o\:
`oo++.
root@bogon:~#

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
root@bogon:~# linuxlogo
_,met$$$$$gg.
,g$$$$$$$$$$$$$$$P.
,g$$P"" """Y$$.".
,$$P' `$$$.
',$$P ,ggs. `$$b:
`d$$' ,$P"' . $$$ ,#.
$$P d$' , $$P ##: :## :###:
$$: $$. - ,d$$' ##' `## `#'
$$; Y$b._ _,d$P' __ ## __ ## __ _ __ _
Y$$. `.`"Y$$$$P"' ,####:## ,######. ##.#####. :### ,######. ###.####:
`$$b "-.__ ,##' `### ##: :## ###' `### ##' #: `## `###' `##:
`Y$$b ## `## ## ## ##' `## ## ___,## ##: `##
`Y$$. ## ## #######: ## ## ## .####### ##' ##
`$$b. ## ## ##' ## ## ## ##' `## ## ##
`Y$$b. ##. ,## ## ## ,## ## ## ## ## ##
`"Y$b._ :#:._,### ##:__,## ##:__,##' ,##. ##.__:##. ## ##
`"""" `:#### ### ######' `######' #### `#####"## ## ##

Linux Version 4.4.0-97-generic, Compiled #120-Ubuntu SMP Tue Sep 19 17:28:18 UTC 2017
Two 2.9GHz Intel i7 Processors, 1.9GB RAM, 11616 Bogomips Total
bogon

root@bogon:~#

阅读全文 »

spring-boot-admin 分为两部分,server和client。
其中,server是监控端,client是被监控端,client就是我们的应用项目。

Server

  1. 创建一个springboot项目,创建项目时选择ops-actuator
  2. 添加依赖,版本保持最新(参考网上教程写demo时,版本是1.3.2,一直启动不起来)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
      <dependency>
    <groupId>de.codecentric</groupId>
    <artifactId>spring-boot-admin-server</artifactId>
    <version>1.5.0</version>
    </dependency>
    <dependency>
    <groupId>de.codecentric</groupId>
    <artifactId>spring-boot-admin-server-ui</artifactId>
    <version>1.5.0</version>
    </dependency>
  3. 配置
1
2
3
4
5
server.port=8090
spring.application.name=Spring Boot Admin Web
spring.boot.admin.url=http://localhost:${server.port}
spring.jackson.serialization.indent_output=true
endpoints.health.sensitive=false
  1. 在SpringBootAdminWebApplication上面添加注解

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    package com.example.admin;

    import de.codecentric.boot.admin.config.EnableAdminServer;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;

    @SpringBootApplication
    @EnableAdminServer
    public class SpringbootDemoAdminServerApplication {

    public static void main(String[] args) {
    SpringApplication.run(SpringbootDemoAdminServerApplication.class, args);
    }
    }
  2. 启动,如果跑起来了就OK了。

  3. 浏览器访问 http://localhost:8090
    效果:
    111111111111111.png

阅读全文 »

  • 配置文件pom.xml
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <packaging>war</packaging>
    -----------------------------------完美分割线
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-tomcat</artifactId>
    <scope>provided</scope>
    </dependency>
    -----------------------------------完美分割线
    <build>
    <finalName>testJenkins</finalName>
    </build>
  • application.properties
    1
    2
    3
    4
    5
    # context-path 和 pom.xml的build-finalName 一致
    server.context-path=/testJenkins

    #如果有指定端口,可以去掉。
    #server.port=9990
  • 编写启动类
    1
    2
    3
    4
    5
    6
    7
    8
    9
    public class TomcatServletInitializer extends SpringBootServletInitializer {

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {

    //Application.class就是springboot的 @SpringBootApplication 类
    return application.sources(Application.class);
    }
    }
  • 命令打包
    1
    mvn package
    参考了此文

Bean 声明注解

  • @Service 业务逻辑层

  • @Component 组件

  • @Repository 数据访问层

  • @Controller Spring mvc 展现层

  • @Configurable 声明当前类是一个配置类!!!

  • @ComponentScan(“com.reachauto.cxn.book.test”)

    1
    2
    设置自动扫描包下面所有的
    @Service @Component @Repository @Controller
  • @EnableAsync

    1
    开启异步任务支持
  • @PropertySource(“classpath:demo.properties”)

    1
    2
    3
    4
    5
    6
    @Component
    @PropertySource("classpath:demo.properties")
    public class Demo {

    @Value("${kk.name}")
    private String aaa;
  • @EnableScheduling 注解开启对计划任务的支持

Bean 注入注解

  • @Autowired Spring 提供
  • @Resource JSR-250
    
  • @Value("xxxx") 注入普通字符串
    
  • @Value("${xxx.xxx}") 注入配置文件中字符串
    
  • @PostConstruct 标注在方法上,在构造函数执行完毕后执行
    
  • @PreDestroy Bean 标注在方法上,销毁前执行
    
  • @Async 异步方法表明,若是在class上则全是
    
  • @Scheduled 声明方法是计划任务
    
  • @Conditional() 条件注解,当满足某条件时
    

Spring MCV

阅读全文 »