diff --git a/bfa_client/src/bfa/node.go b/bfa_client/src/bfa/node.go
index aac88a524d3bc723b3b2347c876f42985816295f..349d9d1f68365605392e955142657d7983feb4eb 100644
--- a/bfa_client/src/bfa/node.go
+++ b/bfa_client/src/bfa/node.go
@@ -44,6 +44,10 @@ type SealerInfo struct {
 	LastBlock    int64
 }
 
+const (
+	Latest = "latest"
+	Self   = "self"
+)
 
 func (node *Node) Call(result interface{}, method string, args ...interface{}) {
 	Check((*rpc.Client)(node).Call(result, method, args...))
@@ -55,7 +59,21 @@ func (node *Node) blockNumber() int64 {
 	return bn.Int64()
 }
 
-
+func (node *Node) Coinbase() (coinbase string, err error) {
+	defer func(){
+		if e := recover(); e != nil {
+			switch s := e.(type){
+			case string: err = fmt.Errorf(s)
+			case error: err = s
+			default: err = fmt.Errorf("unknown error while getting coinbase: %v", e)
+			}
+		}
+	}()
+	var address common.Address
+	node.Call(&address, "eth_coinbase")
+	coinbase = BytesToHex(address[:])
+	return
+}
 
 func (node *Node) GetBlockByNumber(blockNumber int64) types.Header {
 	var (
@@ -63,7 +81,7 @@ func (node *Node) GetBlockByNumber(blockNumber int64) types.Header {
 		resp   types.Header
 	)
 	if blockNumber < 0 {
-		number = "latest"
+		number = Latest
 	} else {
 		number = fmt.Sprintf("0x%x", blockNumber)
 	}
@@ -71,7 +89,6 @@ func (node *Node) GetBlockByNumber(blockNumber int64) types.Header {
 	return resp
 }
 
-
 func (node *Node) GetBlockSigner(blockNumber int64) (signer string) {
 	header := node.GetBlockByNumber(blockNumber)
 	signer, err := GetSigner(&header)
@@ -79,8 +96,6 @@ func (node *Node) GetBlockSigner(blockNumber int64) (signer string) {
 	return
 }
 
-
-
 func (node *Node) GetSnapshot() (snapshot Snapshot) {
 	node.Call(&snapshot, "clique_getSnapshot", nil)
 	return
@@ -129,7 +144,17 @@ func (node *Node) GetSignersAtBlock(blockNumber int64) (signers []string) {
 	return
 }
 
-func (node *Node) Propose(address string, vote bool){
+func (node *Node) IsSealer(address string) bool {
+	if address == Self {
+		var err error
+		if address, err = node.Coinbase(); err != nil {
+			return false
+		}
+	}
+	return Contains(node.GetSigners(), address)
+}
+
+func (node *Node) Propose(address string, vote bool) {
 	node.Call(nil, "clique_propose", address, vote)
 	return
 }
@@ -185,7 +210,7 @@ func (node *Node) SealersStatus(blockNumber int64) (status map[string]int64) {
 	notSeen := int64(len(status))
 	block := node.GetBlockByNumber(blockNumber)
 	blockNumber = block.Number.Int64()
-	until := Max(1, blockNumber - 5*notSeen)
+	until := Max(1, blockNumber-5*notSeen)
 	for notSeen > 0 {
 		signer, _ := GetSigner(&block)
 		if status[signer] == -1 {
@@ -201,7 +226,6 @@ func (node *Node) SealersStatus(blockNumber int64) (status map[string]int64) {
 	return status
 }
 
-
 func (node *Node) GetSealerInception(address string) (since int64) {
 	if signers := node.GetSigners(); !Contains(signers, address) {
 		return -1
@@ -226,7 +250,8 @@ func (node *Node) getSignerFirstBlock(signer string, since int64, until int64) (
 		return -1
 	}
 	//snapshot := node.GetSnapshotAtBlock(since)
-	var (count int64 = 20
+	var (
+		count int64 = 20
 		found int64 = -1
 	)
 	// first, we look close to the inception
@@ -348,7 +373,6 @@ func (node *Node) getSignerLastBlock(signer string, since int64, until int64) (b
 	}
 }
 
-
 func (node *Node) searchSnapshotForward(blockNumber int64, signer string, count int64) (found int64, visited int64) {
 	found = -1
 	if blockNumber+count < 1 {
@@ -392,8 +416,6 @@ func (node *Node) searchSnapshotBackward(blockNumber int64, signer string, count
 	}
 }
 
-
-
 func (node *Node) SealerInfo(sealer string) (info SealerInfo, err error) {
 	info.Address = sealer
 	info.CurrentBlock = node.blockNumber()
@@ -406,8 +428,6 @@ func (node *Node) SealerInfo(sealer string) (info SealerInfo, err error) {
 	return
 }
 
-
-
 func Dial(url string) (*Node, error) {
 	client, err := rpc.Dial(url)
 	return (*Node)(client), err
@@ -416,5 +436,3 @@ func Dial(url string) (*Node, error) {
 func (node *Node) Close() {
 	(*rpc.Client)(node).Close()
 }
-
-
diff --git a/bfa_client/src/client/bfa_client.go b/bfa_client/src/client/bfa_client.go
index d308f45342826ff04ec276d522fa403e791bda01..4121a065fb634280fce51a390f171e2a7def532d 100644
--- a/bfa_client/src/client/bfa_client.go
+++ b/bfa_client/src/client/bfa_client.go
@@ -28,6 +28,7 @@ var (
 	flags       flag.FlagSet
 	command     string
 	description string
+	otherArgs   string
 )
 
 func setFlags() {
@@ -58,7 +59,7 @@ func updateURL(url string) (updated string) {
 }
 
 func usage(errorCode int) {
-	fmt.Fprintf(os.Stderr, "Uso: %v %v [opciones]\n%v\n", os.Args[0], command, description)
+	fmt.Fprintf(os.Stderr, "Uso: %v %v [opciones] %v\n%v\n", os.Args[0], command, otherArgs, description)
 	flags.PrintDefaults()
 	os.Exit(errorCode)
 }
@@ -151,31 +152,48 @@ func sealers() {
 func propose() {
 	var (
 		all bool
-		vote bool
+		authorize bool
 		proposals []string
 	)
 	description = "Vota por una propuesta."
+	otherArgs = "[propuesta...]"
 	setFlags()
 	flags.BoolVar(&all, "all", false, "Vota en todas las propuestas activas")
-	flags.BoolVar(&vote, "vote", true, "Sentido del voto (true: a favor, false: en contra)")
+	flags.BoolVar(&authorize, "authorize", true, "Sentido del voto (true: a favor, false: en contra)")
 	parseFlags()
 	url = updateURL(url)
 	node, err := bfa.Dial(url)
 	util.Check(err)
 	defer node.Close()
+	util.PanicIf(!node.IsSealer(bfa.Self), "Solo los selladores pueden votar")
 	if all {
 		votes := node.GetVotes(latest)
 		for _, proposal := range votes.Proposals {
 			proposals = append(proposals, proposal)
 		}
+		if flags.NArg() != 0 {
+			fmt.Fprintf(os.Stderr, "Se especificó -all. Ignorando argumentos adicionales.")
+		}
 	} else {
+		if flags.NArg() == 0 {
+			panic("No se especificaron candidatos por los cuales votar")
+		}
 		for i := 0; i < flags.NArg(); i++ {
+			address := flags.Arg(i)
+			if !util.IsAddress(address){
+				panic(fmt.Sprintf("'%v' no es una dirección válida", address))
+			}
+			isSealer := node.IsSealer(address)
+			switch {
+			case isSealer && authorize: panic(fmt.Sprintf("'%v' ya es un sellador", address))
+			case !isSealer && !authorize: panic(fmt.Sprintf("'%v' no es un sellador", address))
+			}
 			proposals = append(proposals, flags.Arg(i))
 		}
 	}
 	for _, proposal := range proposals {
-		node.Propose(proposal, vote)
-		fmt.Printf("Voto por %v: %v\n", proposal, vote)
+		node.Propose(proposal, authorize)
+		fmt.Printf("Voto por %v: %v\n", proposal, authorize)
 	}
 }
 
diff --git a/bfa_client/src/util/util.go b/bfa_client/src/util/util.go
index 610bcca8a48ca629c54e7486a0b785c960126f02..0e651cca4d1653458e9e24e61e364ca9870c241f 100644
--- a/bfa_client/src/util/util.go
+++ b/bfa_client/src/util/util.go
@@ -1,8 +1,10 @@
 package util
 
 import (
+	"encoding/hex"
 	"encoding/json"
 	"fmt"
+	"github.com/ethereum/go-ethereum/common"
 	"runtime"
 	"strconv"
 )
@@ -57,5 +59,16 @@ func PrintJson(s interface{}){
 }
 
 
+func IsAddress(address string) bool {
+	bytes, err := hex.DecodeString(address[2:])
+	return err == nil && len(bytes) == common.AddressLength
+}
+
+func PanicIf(cond bool, format string, args ...interface{}){
+	if cond {
+		panic(fmt.Sprintf(format, args...))
+	}
+}
+